Results Study 3: Personality Change Through Self-Improvement or Self-Acceptance
Author
[blinded]
1 Load packages
Show the code
library(renv)library(tidyverse)library(broom)library(labelled)library(psych)library(GPArotation)#library(devtools)#install_github("cran/multicon") # not on CRAN atmlibrary(multicon)library(correlation)library(careless)library(corrplot)library(lavaan)library(semTools)library(semPlot)library(knitr)library(ggdist)library(ggforce)library(cowplot)library(nortest)library(lmerTest)library(effectsize)
2 Data cleaning
Show the code
# source("clean_data_st3.R") # for data protection reasons, we provide the cleaned data sets here where potentially sensitive variables were dropped (see "clean_data_st3.R" for details)base::load("data/df_sbsa3.rda")
This is only relevant for the facet-level models. All trait-level models rely on the parcels created above. However, the facet-level models pick the first item as the anchor indicator which is sometimes reverse-keyed for the latent factor. For analyses below I want to use just positively keyed variables (for neuroticism facets higher values should indicate higher neuroticism).
# save all relevant variable namesnames_rev_scored <- df_sbsa3_wide_pers %>%select(ends_with("_r")) %>%colnames()names_rev_scored_orig <-gsub("_r", "", names_rev_scored) # variable names without the "_r" -> these are the original variables# drop original variablesdf_sbsa3_wide_pers <- df_sbsa3_wide_pers %>%select(-all_of(names_rev_scored_orig))# recreate original variable names -> these are the recoded variables now!df_sbsa3_wide_pers <- df_sbsa3_wide_pers %>%rename_with(~gsub("_r", "", .x))
4 Measurement invariance
4.1 Well-being outcomes
Testing for measurement invariance of the latent traits across time.
4.1.1 Life satisfaction
Satisfaction with life scale (only the first four items - last one taps into a somewhat different construct)
Satisfactory model fit across all stages of measurement invariance (except for RMSEA). Chi^2 tests indicate that strict measurement invariance is given.
Good model fit across all stages of measurement invariance (except for RMSEA). Chi^2 tests indicate that weak measurement invariance is given (at p < .05; strict at p < .01).
Good model fit across all stages of measurement invariance. Chi^2 tests indicate that weak measurement invariance is given (at p < .05; strict at p < .01).
Model fit satisfactory (except for RMSEA) across all stages of measurement invariance. Chi^2 tests indicate that strict measurement invariance is given.
5 Descriptives
5.1 Sample size
How many participants at each time point and in each condition?
df_sbsa3 %>%summarise(n_distinct(pid)) # N (after exclusions)
# A tibble: 1 × 1
`n_distinct(pid)`
<int>
1 530
df_sbsa3 %>%group_by(time, group) %>%tally()
# A tibble: 6 × 3
# Groups: time [2]
time group n
<dbl> <chr> <int>
1 1 Group 1 174
2 1 Group 2 179
3 1 Group 3 176
4 2 Group 1 155
5 2 Group 2 152
6 2 Group 3 159
One in Group 1 only has T2 data.
5.2 Demographics
Gender and age distribution
# across all participantsdf_sbsa3 %>%group_by(pid) %>%slice_head(n=1) %>%ungroup() %>%mutate(gender_num =ifelse(gender=="Female", 1, 0)) %>%summarise(n =n(), women =sum(gender_num), m_age =mean(age, na.rm=T), sd_age =sd(age, na.rm=T), min_age =min(age, na.rm=T), max_age =max(age, na.rm=T)) %>%kable(digits =2)
n
women
m_age
sd_age
min_age
max_age
530
265
31.17
10.11
19
105
# by group and time pointdf_sbsa3 %>%group_by(time, group) %>%summarise(n =n(), m_age =mean(age, na.rm=T), sd_age =sd(age, na.rm=T), min_age =min(age, na.rm=T), max_age =max(age, na.rm=T)) %>%kable(digits =2)
Not in paid work (e.g. homemaker’, ’retired or disabled)
22
4.2
Due to start a new job within the next month
11
2.1
5.3 Internal consistencies
On the trait/dimensional level:
# created in study 3 cleaning script base::load("data/int_consist_traits_st3.rda")kable(int_consist_traits_st3, digits =3)
trait
rel_alpha_current
rel_alpha_ideal
rel_omega_t_current
rel_omega_t_ideal
rel_omega_h_current
rel_omega_h_ideal
lifesat
0.874
NA
0.895
NA
0.828
NA
meaning
0.867
NA
0.948
NA
0.580
NA
selfes
0.909
NA
0.936
NA
0.833
NA
concept
0.893
NA
0.914
NA
0.860
NA
extra
0.862
0.730
0.893
0.773
0.688
0.480
agree
0.789
0.741
0.842
0.806
0.584
0.595
consc
0.871
0.732
0.896
0.796
0.683
0.579
neuro
0.913
0.749
0.928
0.803
0.757
0.562
openn
0.814
0.745
0.856
0.808
0.691
0.602
McDonald’s omega only really makes sense for the Big Five dimensions (with their three facets each) but I’ve added it for the well-being measures as well. Keep in mind that a few of the omega computations for the well-being measures only converged with error messages. These constructs were not neccessarily intended to be tested in this multidimensional manner for internal consistency.
On the facet level:
# created in study 3 cleaning script base::load("data/int_consist_facets_st3.rda")kable(int_consist_facets_st3, digits =3)
facet
rel_alpha_current
rel_alpha_ideal
socia
0.830
0.621
asser
0.748
0.546
energ
0.737
0.423
compa
0.544
0.386
respe
0.686
0.616
trust
0.677
0.612
organ
0.835
0.519
produ
0.778
0.622
respo
0.635
0.407
anxie
0.791
0.402
depre
0.836
0.508
volat
0.827
0.578
curio
0.635
0.534
aesth
0.646
0.415
imagi
0.730
0.618
5.4 Attrition analyses
Do participants who only took part in T1 differ from those taking part in T1 and T2?
Determine groups of “remainers” vs. “drop-outs” and run analyses:
Show the code
attrition_sample <- df_sbsa3 %>%group_by(pid) %>%mutate(last_time =max(time)) %>%ungroup() %>%filter(time==1) %>%select(pid, last_time, contains("_comb_"), c("swls", "meaning", "selfes", "concept"), # outcomes gender, age, ethnicity, student, employed) %>%# demographicsmutate(remained = last_time -1,female =if_else(gender=="Female", 1, 0, NA_real_),white =if_else(ethnicity=="White", 1, 0, NA_real_),black =if_else(ethnicity=="Black", 1, 0, NA_real_),student =if_else(student=="Yes", 1, 0, NA_real_),fulltime =if_else(employed=="Full-Time", 1, 0, NA_real_),parttime =if_else(employed=="Part-Time", 1, 0, NA_real_),notemployed =if_else(employed=="Unemployed (and job seeking)"| employed=="Not in paid work (e.g. homemaker', 'retired or disabled)"| employed=="Due to start a new job within the next month", 1, 0, NA_real_),) %>%select(-c(last_time, na_comb_curr, na_comb_ideal, gender, ethnicity, employed))attrition_analysis <-colnames(attrition_sample) %>%# Start with all column namessetdiff( c("pid", "remained" ) ) %>%# ...that are not Sepal.Length rlang::syms() %>%# Convert them to symbolsmap( ~rlang::expr(lm(!!.x ~ remained,data=attrition_sample)) ) %>%# Create expressionsmap( eval.parent ) %>%# Evaluate expressionsmap( broom::tidy ) %>%# Tidy up the outputbind_rows() %>%# Combine into a single data framefilter( term !="(Intercept)" ) %>%# Drop all (Intercept) entriesmutate(outcome =colnames(attrition_sample) %>%setdiff( c("pid", "remained" ) ))
# A tibble: 4 × 6
term estimate std.error statistic p.value outcome
<chr> <dbl> <dbl> <dbl> <dbl> <chr>
1 remained 0.230 0.0957 2.41 0.0164 compa_comb_curr
2 remained 0.179 0.0663 2.70 0.00724 female
3 remained 0.142 0.0549 2.59 0.00985 black
4 remained -0.127 0.0640 -1.98 0.0482 white
effectsize::cohens_d(compa_comb_curr ~ remained, data = attrition_sample)
Cohen's d | 95% CI
--------------------------
-0.32 | [-0.58, -0.06]
- Estimated using pooled SD.
effectsize::phi(table(attrition_sample$female, attrition_sample$remained), alternative ="two.sided")
Phi (adj.) | 95% CI
-------------------------
0.11 | [0.00, 0.20]
effectsize::phi(table(attrition_sample$black, attrition_sample$remained), alternative ="two.sided")
Phi (adj.) | 95% CI
-------------------------
0.10 | [0.00, 0.19]
effectsize::phi(table(attrition_sample$white, attrition_sample$remained), alternative ="two.sided")
Phi (adj.) | 95% CI
-------------------------
0.07 | [0.00, 0.17]
Participants who dropped out at T2 were less compassionate, d = -0.32, 95% CI [-0.58; -0.06], p = .016, less likely to be female, phi = .11, 95% CI [0; .20], p = .007, and Black, phi = .10, 95% CI [0; .19], p = .001, and more likely to be White, phi = .07, 95% CI [0; .17], p = .048.
For Study 3, most of these moedls are only possible in Group 1 which answered both current and ideal personality trait items.
I only left the heading “confirmatory” here for better comparability with Study 1 and Study 2 analyses. The preregistered, confirmatory analyses for Study 3 are found below in section 7!
6.1 Well-being - similarity correlations (H4 in paper)
All four psychological well-being indicators will be positively correlated with a greater similarity between current- and ideal personality-ratings of personality.
To examine this at the level of overall profiles, we will compute the correlations between the psychological well-being indicators and the Fisher z transformed correlations between the facet- and item-level real-ideal personality-profiles. To examine this at the level of individual traits, we will compute the correlation between psychological well-being indicators and the squared difference between current- and ideal personality rating for each Big Five trait and facet.
In Study 3, we can only examine this in Group 3 because the other groups only received current personality items.
corrplot(cormat_profile, type ="lower", order ="original", tl.col ="black", tl.srt =10,addCoef.col ='black', number.cex =0.7, diag =FALSE) # also add numbers
Positive correlations of well-being indicators with profile similarity between current personality and ideal personality personality. Especially high correlation with self-esteem. High congruence of item-level and facet-level profile similarity.
As a table with confidence intervals - profile similarity:
corrplot(cormat_sqfacets, type ="lower", order ="original", tl.col ="black", tl.srt =10,addCoef.col ='black', number.cex =0.6, diag =FALSE) # also add numbers
Here we see negative correlations of well-being indicators with squared trait- and facet-level mean-score differences between current personality and ideal personality personality. Especially pronounced negative correlations for neuroticism, extraversion, and conscientiousness (in that order).
6.1.2.1 Change in this relation over time and across intervention groups
corrplot(cormat_sqtraits_gr1_t1, type ="lower", order ="original", tl.col ="black", tl.srt =10,addCoef.col ='black', number.cex =0.7, diag =FALSE) # also add numbers
T2
Second assessment:
corrplot(cormat_sqtraits_gr1_t2, type ="lower", order ="original", tl.col ="black", tl.srt =10,addCoef.col ='black', number.cex =0.7, diag =FALSE) # also add numbers
At T2, slightly lower correlations for openness. Relatively similar results across time, otherwise.
6.1.2.2 Exploratory: Controlling for initial trait levels
Additional, exploratory analysis: Are the relationships of the squared trait differences with well-being similar when we control for initial trait levels (at T1)?
# basic model to replicate the correlationmod_ex_1 <-lm(swls ~ extra_sqdiff, data = df_sbsa3 %>%filter(group=="Group 1"& time==1))summary(mod_ex_1)$coef
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.989693 0.09815233 30.459725 3.331613e-71
extra_sqdiff -0.135079 0.03689506 -3.661167 3.338466e-04
Does the relationship between the squared difference in one trait (current vs. ideal) and well-being aspects still hold if we control for the initial trait level?
Does the relationship between the squared difference in one trait (current vs. ideal) and well-being aspects still hold if we control for the initial trait level?
Effects mostly not significant, anymore, but much smaller sample size here in Study 3 (only Group 1). Exceptions: productiveness, depression & life satisfaction. Depression & meaning in life. Sociability & self-esteem.
6.2 Well-being - latent change (H5 in paper)
Both groups will increase in all four psychological well-being indicators.
We will test the mean-level difference between baseline and follow up using a latent change model.
6.2.1 Life satisfaction
Fit model:
Show the code
# Code snippets adapted from Kievit et al. (2018) -- CC-BY -- https://doi.org/10.1016/j.dcn.2017.11.007# Fit the multiple indicator Univariate Latent Change Score modelmi_lcs_swls_hyp2 <-'swls_t1 =~ 1*sw06_01_t1 + lamb2*sw06_02_t1 + lamb3*sw06_03_t1 + lamb4*sw06_04_t1 # This specifies the measurement model for swls_t1 swls_t2 =~ 1*sw06_01_t2 + lamb2*sw06_02_t2 + lamb3*sw06_03_t2 + lamb4*sw06_04_t2 # This specifies the measurement model for swls_t2 with the equality constrained factor loadingsswls_t2 ~ 1*swls_t1 # This parameter regresses swls_t2 perfectly on swls_t1d_swls_1 =~ 1*swls_t2 # This defines the latent change score factor as measured perfectly by scores on swls_t2swls_t2 ~ 0*1 # This line constrains the intercept of swls_t2 to 0swls_t2 ~~ 0*swls_t2 # This fixes the variance of swls_t2 to 0d_swls_1 ~ 1 # This estimates the intercept of the change score swls_t1 ~ 1 # This estimates the intercept of swls_t1 d_swls_1 ~~ d_swls_1 # This estimates the variance of the change scores swls_t1 ~~ swls_t1 # This estimates the variance of the swls_t1 d_swls_1 ~~ swls_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change score remains unconditionalsw06_01_t1 ~~ sw06_01_t2 # This allows residual covariance on indicator X1 across T1 and T2sw06_02_t1 ~~ sw06_02_t2 # This allows residual covariance on indicator X2 across T1 and T2sw06_03_t1 ~~ sw06_03_t2 # This allows residual covariance on indicator X3 across T1 and T2sw06_04_t1 ~~ sw06_04_t2 # This allows residual covariance on indicator X4 across T1 and T2sw06_01_t1 ~~ res1*sw06_01_t1 # This allows residual variance on indicator X1 at T1 sw06_02_t1 ~~ res2*sw06_02_t1 # This allows residual variance on indicator X2 at T1sw06_03_t1 ~~ res3*sw06_03_t1 # This allows residual variance on indicator X3 at T1sw06_04_t1 ~~ res4*sw06_04_t1 # This allows residual variance on indicator X4 at T1sw06_01_t2 ~~ res1*sw06_01_t2 # This allows residual variance on indicator X1 at T2 sw06_02_t2 ~~ res2*sw06_02_t2 # This allows residual variance on indicator X2 at T2 sw06_03_t2 ~~ res3*sw06_03_t2 # This allows residual variance on indicator X3 at T2sw06_04_t2 ~~ res4*sw06_04_t2 # This allows residual variance on indicator X4 at T2sw06_01_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1sw06_02_t1 ~ m2*1 # This estimates the intercept of X2 at T1sw06_03_t1 ~ m3*1 # This estimates the intercept of X3 at T1sw06_04_t1 ~ m4*1 # This estimates the intercept of X4 at T1sw06_01_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2sw06_02_t2 ~ m2*1 # This estimates the intercept of X2 at T2sw06_03_t2 ~ m3*1 # This estimates the intercept of X3 at T2sw06_04_t2 ~ m4*1 # This estimates the intercept of X4 at T2'fit_mi_lcs_swls_hyp2 <-lavaan(mi_lcs_swls_hyp2, data=df_sbsa3_wide_wb, estimator='mlr', fixed.x=FALSE, missing='fiml')summary(fit_mi_lcs_swls_hyp2, fit.measures=TRUE, standardized=TRUE, rsquare=F)
Significantly higher life satisfaction at the post test, b = 0.156, beta = 0.275, p = 0. Those with initially higher levels of life satisfaction (at T1) change to a lesser degree.
6.2.2 Meaning in life
Fit model:
Show the code
# Code snippets adapted from Kievit et al. (2018) -- CC-BY -- https://doi.org/10.1016/j.dcn.2017.11.007# Fit the multiple indicator Univariate Latent Change Score modelmi_lcs_meaning_hyp2 <-'meaning_t1 =~ 1*meaning_par1_t1 + lamb2*meaning_par2_t1 + lamb3*meaning_par3_t1 # This specifies the measurement model for meaning_t1 meaning_t2 =~ 1*meaning_par1_t2 + lamb2*meaning_par2_t2 + lamb3*meaning_par3_t2 # This specifies the measurement model for meaning_t2 with the equality constrained factor loadingsmeaning_t2 ~ 1*meaning_t1 # This parameter regresses meaning_t2 perfectly on meaning_t1d_meaning_1 =~ 1*meaning_t2 # This defines the latent change score factor as measured perfectly by scores on meaning_t2meaning_t2 ~ 0*1 # This line constrains the intercept of meaning_t2 to 0meaning_t2 ~~ 0*meaning_t2 # This fixes the variance of meaning_t2 to 0d_meaning_1 ~ 1 # This estimates the intercept of the change score meaning_t1 ~ 1 # This estimates the intercept of meaning_t1 d_meaning_1 ~~ d_meaning_1 # This estimates the variance of the change scores meaning_t1 ~~ meaning_t1 # This estimates the variance of the meaning_t1 d_meaning_1 ~~ meaning_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change score remains unconditionalmeaning_par1_t1 ~~ meaning_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2meaning_par2_t1 ~~ meaning_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2meaning_par3_t1 ~~ meaning_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2meaning_par1_t1 ~~ res1*meaning_par1_t1 # This allows residual variance on indicator X1 at T1 meaning_par2_t1 ~~ res2*meaning_par2_t1 # This allows residual variance on indicator X2 at T1meaning_par3_t1 ~~ res3*meaning_par3_t1 # This allows residual variance on indicator X3 at T1meaning_par1_t2 ~~ res1*meaning_par1_t2 # This allows residual variance on indicator X1 at T2 meaning_par2_t2 ~~ res2*meaning_par2_t2 # This allows residual variance on indicator X2 at T2 meaning_par3_t2 ~~ res3*meaning_par3_t2 # This allows residual variance on indicator X3 at T2meaning_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1meaning_par2_t1 ~ m2*1 # This estimates the intercept of X2 at T1meaning_par3_t1 ~ m3*1 # This estimates the intercept of X3 at T1meaning_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2meaning_par2_t2 ~ m2*1 # This estimates the intercept of X2 at T2meaning_par3_t2 ~ m3*1 # This estimates the intercept of X3 at T2'fit_mi_lcs_meaning_hyp2 <-lavaan(mi_lcs_meaning_hyp2, data=df_sbsa3_wide_wb, estimator='mlr', fixed.x=FALSE, missing='fiml')summary(fit_mi_lcs_meaning_hyp2, fit.measures=TRUE, standardized=TRUE, rsquare=F)
Participants improved significantly in meaning in life across time, b = 0.1, beta = 0.176, p = 0.001.
6.2.3 Self-esteem
Fit model:
Show the code
# Code snippets adapted from Kievit et al. (2018) -- CC-BY -- https://doi.org/10.1016/j.dcn.2017.11.007# Fit the multiple indicator Univariate Latent Change Score modelmi_lcs_selfes_hyp2 <-'selfes_t1 =~ 1*selfes_par1_t1 + lamb2*selfes_par2_t1 + lamb3*selfes_par3_t1 # This specifies the measurement model for selfes_t1 selfes_t2 =~ 1*selfes_par1_t2 + lamb2*selfes_par2_t2 + lamb3*selfes_par3_t2 # This specifies the measurement model for selfes_t2 with the equality constrained factor loadingsselfes_t2 ~ 1*selfes_t1 # This parameter regresses selfes_t2 perfectly on selfes_t1d_selfes_1 =~ 1*selfes_t2 # This defines the latent change score factor as measured perfectly by scores on selfes_t2selfes_t2 ~ 0*1 # This line constrains the intercept of selfes_t2 to 0selfes_t2 ~~ 0*selfes_t2 # This fixes the variance of selfes_t2 to 0d_selfes_1 ~ 1 # This estimates the intercept of the change score selfes_t1 ~ 1 # This estimates the intercept of selfes_t1 d_selfes_1 ~~ d_selfes_1 # This estimates the variance of the change scores selfes_t1 ~~ selfes_t1 # This estimates the variance of the selfes_t1 d_selfes_1 ~~ selfes_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change score remains unconditionalselfes_par1_t1 ~~ selfes_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2selfes_par2_t1 ~~ selfes_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2selfes_par3_t1 ~~ selfes_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2selfes_par1_t1 ~~ res1*selfes_par1_t1 # This allows residual variance on indicator X1 at T1 selfes_par2_t1 ~~ res2*selfes_par2_t1 # This allows residual variance on indicator X2 at T1selfes_par3_t1 ~~ res3*selfes_par3_t1 # This allows residual variance on indicator X3 at T1selfes_par1_t2 ~~ res1*selfes_par1_t2 # This allows residual variance on indicator X1 at T2 selfes_par2_t2 ~~ res2*selfes_par2_t2 # This allows residual variance on indicator X2 at T2 selfes_par3_t2 ~~ res3*selfes_par3_t2 # This allows residual variance on indicator X3 at T2selfes_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1selfes_par2_t1 ~ m2*1 # This estimates the intercept of X2 at T1selfes_par3_t1 ~ m3*1 # This estimates the intercept of X3 at T1selfes_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2selfes_par2_t2 ~ m2*1 # This estimates the intercept of X2 at T2selfes_par3_t2 ~ m3*1 # This estimates the intercept of X3 at T2'fit_mi_lcs_selfes_hyp2 <-lavaan(mi_lcs_selfes_hyp2, data=df_sbsa3_wide_wb, estimator='mlr', fixed.x=FALSE, missing='fiml')summary(fit_mi_lcs_selfes_hyp2, fit.measures=TRUE, standardized=TRUE, rsquare=F)
Participants increased significantly in self-esteem between the two assessments, b = 0.093, beta = 0.234, p = 0.
6.2.4 Self concept clarity
Fit model:
Show the code
# Code snippets adapted from Kievit et al. (2018) -- CC-BY -- https://doi.org/10.1016/j.dcn.2017.11.007# Fit the multiple indicator Univariate Latent Change Score modelmi_lcs_concept_hyp2 <-'concept_t1 =~ 1*concept_par1_t1 + lamb2*concept_par2_t1 + lamb3*concept_par3_t1 # This specifies the measurement model for concept_t1 concept_t2 =~ 1*concept_par1_t2 + lamb2*concept_par2_t2 + lamb3*concept_par3_t2 # This specifies the measurement model for concept_t2 with the equality constrained factor loadingsconcept_t2 ~ 1*concept_t1 # This parameter regresses concept_t2 perfectly on concept_t1d_concept_1 =~ 1*concept_t2 # This defines the latent change score factor as measured perfectly by scores on concept_t2concept_t2 ~ 0*1 # This line constrains the intercept of concept_t2 to 0concept_t2 ~~ 0*concept_t2 # This fixes the variance of concept_t2 to 0d_concept_1 ~ 1 # This estimates the intercept of the change score concept_t1 ~ 1 # This estimates the intercept of concept_t1 d_concept_1 ~~ d_concept_1 # This estimates the variance of the change scores concept_t1 ~~ concept_t1 # This estimates the variance of the concept_t1 d_concept_1 ~~ concept_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change score remains unconditionalconcept_par1_t1 ~~ concept_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2concept_par2_t1 ~~ concept_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2concept_par3_t1 ~~ concept_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2concept_par1_t1 ~~ res1*concept_par1_t1 # This allows residual variance on indicator X1 at T1 concept_par2_t1 ~~ res2*concept_par2_t1 # This allows residual variance on indicator X2 at T1concept_par3_t1 ~~ res3*concept_par3_t1 # This allows residual variance on indicator X3 at T1concept_par1_t2 ~~ res1*concept_par1_t2 # This allows residual variance on indicator X1 at T2 concept_par2_t2 ~~ res2*concept_par2_t2 # This allows residual variance on indicator X2 at T2 concept_par3_t2 ~~ res3*concept_par3_t2 # This allows residual variance on indicator X3 at T2concept_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1concept_par2_t1 ~ m2*1 # This estimates the intercept of X2 at T1concept_par3_t1 ~ m3*1 # This estimates the intercept of X3 at T1concept_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2concept_par2_t2 ~ m2*1 # This estimates the intercept of X2 at T2concept_par3_t2 ~ m3*1 # This estimates the intercept of X3 at T2'fit_mi_lcs_concept_hyp2 <-lavaan(mi_lcs_concept_hyp2, data=df_sbsa3_wide_wb, estimator='mlr', fixed.x=FALSE, missing='fiml')summary(fit_mi_lcs_concept_hyp2, fit.measures=TRUE, standardized=TRUE, rsquare=F)
Self concept clarity improved significantly across time, b = 0.105, beta = 0.236, p = 0.
6.3 Distance between ideal- and current personality over time (H1 in paper)
The distance between ideal- and current personality will decrease in both groups.
We will use two strategies to test this hypothesis. First, we will compute the Fisher z-transformed profile correlation between current- and ideal personality and test whether it increased across assessments. Second, we will test whether the squared difference between current- and ideal personality ratings for each Big Five trait decreased across assessments. We will test mean-level differences in profile correlations and squared differences between baseline and follow up using repeated-measures t-test.
In Study 3, we can only test this in Group 1 where we assessed both current and ideal personality ratings.
6.3.1 Profile similarity
Reshape to wide:
Show the code
# reshape to widedf_sbsa3_wide_profdiff <- df_sbsa3 %>%filter(group=="Group 1") %>%# not possible in the other groupsarrange(pid, time) %>%select(pid, time, profile_corr_item_z, profile_corr_facet_z, ends_with("_sqdiff")) %>%pivot_wider(names_from = time,names_sep ="_t",values_from =-c(pid, time))
profile_df_plot <- df_sbsa3 %>%filter(group=="Group 1") %>%select(pid, time, profile_corr_item_z, profile_corr_facet_z) %>%pivot_longer(-c(pid, time), names_to ="itemfacet", values_to ="corr") %>%mutate(itemfacet2 =fct_recode(itemfacet, "Item-level"="profile_corr_item_z", "Facet-level"="profile_corr_facet_z"),itemfacet2 =fct_reorder(itemfacet2, corr, .desc = F))ggplot(profile_df_plot) +aes(x =as.factor(time), y = corr) +geom_boxplot() +geom_violin(fill =NA) +facet_wrap(vars(itemfacet2)) +labs(x ="Measurement Occasion", y ="Profile correlation") +# title = "Distance between ideal- and current personality"theme_bw()
Significantly higher profile correlations at the second measurement occasion, both for the item-level profile correlation and the facet-level profile correlations.
[Note: These CIs for d are probably “wrong” -> not appropriate for paired t-test]
Significantly lower squared mean-level differences at the second measurement occasion for extraversion and conscientiousness, but not for the rest of the Big Five traits and their 15 BFI-2 facets (at p < .01). Except for depression where the squared mean-level differences also decline significantly.
Plot (traits/facets sorted by average size of squared differences)
Distributions only look different for some of the facets (mostly E and C plus .
6.4 Latent change in Big Five
Amount of change on the latent level collapsed across all groups.
We will test the mean-level difference between baseline and follow up using a latent change model.
6.4.1 Extraversion
Fit model:
Show the code
# Fit the multiple indicator Univariate Latent Change Score modelmi_lcs_extra_hyp2 <-'extra_t1 =~ 1*extra_curr_par1_t1 + lamb2*extra_curr_par2_t1 + lamb3*extra_curr_par3_t1 # Measurement model T1extra_t2 =~ 1*extra_curr_par1_t2 + lamb2*extra_curr_par2_t2 + lamb3*extra_curr_par3_t2 # Measurement model T2 with the equality constrained factor loadingsextra_t2 ~ 1*extra_t1 # This parameter regresses extra_t2 perfectly on extra_t1d_extra_1 =~ 1*extra_t2 # This defines the latent change score factor as measured perfectly by scores on extra_t2extra_t2 ~ 0*1 # This line constrains the intercept of extra_t2 to 0extra_t2 ~~ 0*extra_t2 # This fixes the variance of extra_t2 to 0d_extra_1 ~ 1 # This estimates the intercept of the change score extra_t1 ~ 1 # This estimates the intercept of extra_t1 d_extra_1 ~~ d_extra_1 # This estimates the variance of the change scores extra_t1 ~~ extra_t1 # This estimates the variance of the extra_t1 d_extra_1 ~~ extra_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change score remains unconditionalextra_curr_par1_t1 ~~ extra_curr_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2extra_curr_par2_t1 ~~ extra_curr_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2extra_curr_par3_t1 ~~ extra_curr_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2extra_curr_par1_t1 ~~ res1*extra_curr_par1_t1 # This allows residual variance on indicator X1 at T1 extra_curr_par2_t1 ~~ res2*extra_curr_par2_t1 # This allows residual variance on indicator X2 at T1extra_curr_par3_t1 ~~ res3*extra_curr_par3_t1 # This allows residual variance on indicator X3 at T1extra_curr_par1_t2 ~~ res1*extra_curr_par1_t2 # This allows residual variance on indicator X1 at T2 extra_curr_par2_t2 ~~ res2*extra_curr_par2_t2 # This allows residual variance on indicator X2 at T2 extra_curr_par3_t2 ~~ res3*extra_curr_par3_t2 # This allows residual variance on indicator X3 at T2extra_curr_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1extra_curr_par2_t1 ~ m2*1 # This estimates the intercept of X2 at T1extra_curr_par3_t1 ~ m3*1 # This estimates the intercept of X3 at T1extra_curr_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2extra_curr_par2_t2 ~ m2*1 # This estimates the intercept of X2 at T2extra_curr_par3_t2 ~ m3*1 # This estimates the intercept of X3 at T2'fit_mi_lcs_extra_hyp2 <-lavaan(mi_lcs_extra_hyp2, data=df_sbsa3_wide_pers, estimator='mlr', fixed.x=FALSE, missing='fiml')summary(fit_mi_lcs_extra_hyp2, fit.measures=TRUE, standardized=TRUE, rsquare=F)
Significantly higher extraversion at the post test, b = 0.043, beta = 0.18, p = 0.01.
6.4.2 Agreeableness
Fit model:
Show the code
# Fit the multiple indicator Univariate Latent Change Score modelmi_lcs_agree_hyp2 <-'agree_t1 =~ 1*agree_curr_par1_t1 + lamb2*agree_curr_par2_t1 + lamb3*agree_curr_par3_t1 # Measurement model T1agree_t2 =~ 1*agree_curr_par1_t2 + lamb2*agree_curr_par2_t2 + lamb3*agree_curr_par3_t2 # Measurement model T2 with the equality constrained factor loadingsagree_t2 ~ 1*agree_t1 # This parameter regresses agree_t2 perfectly on agree_t1d_agree_1 =~ 1*agree_t2 # This defines the latent change score factor as measured perfectly by scores on agree_t2agree_t2 ~ 0*1 # This line constrains the intercept of agree_t2 to 0agree_t2 ~~ 0*agree_t2 # This fixes the variance of agree_t2 to 0d_agree_1 ~ 1 # This estimates the intercept of the change score agree_t1 ~ 1 # This estimates the intercept of agree_t1 d_agree_1 ~~ d_agree_1 # This estimates the variance of the change scores agree_t1 ~~ agree_t1 # This estimates the variance of the agree_t1 d_agree_1 ~~ agree_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change score remains unconditionalagree_curr_par1_t1 ~~ agree_curr_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2agree_curr_par2_t1 ~~ agree_curr_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2agree_curr_par3_t1 ~~ agree_curr_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2agree_curr_par1_t1 ~~ res1*agree_curr_par1_t1 # This allows residual variance on indicator X1 at T1 agree_curr_par2_t1 ~~ res2*agree_curr_par2_t1 # This allows residual variance on indicator X2 at T1agree_curr_par3_t1 ~~ res3*agree_curr_par3_t1 # This allows residual variance on indicator X3 at T1agree_curr_par1_t2 ~~ res1*agree_curr_par1_t2 # This allows residual variance on indicator X1 at T2 agree_curr_par2_t2 ~~ res2*agree_curr_par2_t2 # This allows residual variance on indicator X2 at T2 agree_curr_par3_t2 ~~ res3*agree_curr_par3_t2 # This allows residual variance on indicator X3 at T2agree_curr_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1agree_curr_par2_t1 ~ m2*1 # This estimates the intercept of X2 at T1agree_curr_par3_t1 ~ m3*1 # This estimates the intercept of X3 at T1agree_curr_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2agree_curr_par2_t2 ~ m2*1 # This estimates the intercept of X2 at T2agree_curr_par3_t2 ~ m3*1 # This estimates the intercept of X3 at T2'fit_mi_lcs_agree_hyp2 <-lavaan(mi_lcs_agree_hyp2, data=df_sbsa3_wide_pers, estimator='mlr', fixed.x=FALSE, missing='fiml')summary(fit_mi_lcs_agree_hyp2, fit.measures=TRUE, standardized=TRUE, rsquare=F)
No significant changes in agreeableness from pre to post test, b = 0.026, beta = 0.11, p = 0.092.
6.4.3 Conscientiousness
Fit model:
Show the code
# Fit the multiple indicator Univariate Latent Change Score modelmi_lcs_consc_hyp2 <-'consc_t1 =~ 1*consc_curr_par1_t1 + lamb2*consc_curr_par2_t1 + lamb3*consc_curr_par3_t1 # Measurement model T1consc_t2 =~ 1*consc_curr_par1_t2 + lamb2*consc_curr_par2_t2 + lamb3*consc_curr_par3_t2 # Measurement model T2 with the equality constrained factor loadingsconsc_t2 ~ 1*consc_t1 # This parameter regresses consc_t2 perfectly on consc_t1d_consc_1 =~ 1*consc_t2 # This defines the latent change score factor as measured perfectly by scores on consc_t2consc_t2 ~ 0*1 # This line constrains the intercept of consc_t2 to 0consc_t2 ~~ 0*consc_t2 # This fixes the variance of consc_t2 to 0d_consc_1 ~ 1 # This estimates the intercept of the change score consc_t1 ~ 1 # This estimates the intercept of consc_t1 d_consc_1 ~~ d_consc_1 # This estimates the variance of the change scores consc_t1 ~~ consc_t1 # This estimates the variance of the consc_t1 d_consc_1 ~~ consc_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change score remains unconditionalconsc_curr_par1_t1 ~~ consc_curr_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2consc_curr_par2_t1 ~~ consc_curr_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2consc_curr_par3_t1 ~~ consc_curr_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2consc_curr_par1_t1 ~~ res1*consc_curr_par1_t1 # This allows residual variance on indicator X1 at T1 consc_curr_par2_t1 ~~ res2*consc_curr_par2_t1 # This allows residual variance on indicator X2 at T1consc_curr_par3_t1 ~~ res3*consc_curr_par3_t1 # This allows residual variance on indicator X3 at T1consc_curr_par1_t2 ~~ res1*consc_curr_par1_t2 # This allows residual variance on indicator X1 at T2 consc_curr_par2_t2 ~~ res2*consc_curr_par2_t2 # This allows residual variance on indicator X2 at T2 consc_curr_par3_t2 ~~ res3*consc_curr_par3_t2 # This allows residual variance on indicator X3 at T2consc_curr_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1consc_curr_par2_t1 ~ m2*1 # This estimates the intercept of X2 at T1consc_curr_par3_t1 ~ m3*1 # This estimates the intercept of X3 at T1consc_curr_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2consc_curr_par2_t2 ~ m2*1 # This estimates the intercept of X2 at T2consc_curr_par3_t2 ~ m3*1 # This estimates the intercept of X3 at T2'fit_mi_lcs_consc_hyp2 <-lavaan(mi_lcs_consc_hyp2, data=df_sbsa3_wide_pers, estimator='mlr', fixed.x=FALSE, missing='fiml')summary(fit_mi_lcs_consc_hyp2, fit.measures=TRUE, standardized=TRUE, rsquare=F)
Significantly higher conscientiousness at the post test, b = 0.068, beta = 0.255, p = 0.
6.4.4 Neuroticism
Fit model:
Show the code
# Fit the multiple indicator Univariate Latent Change Score modelmi_lcs_neuro_hyp2 <-'neuro_t1 =~ 1*neuro_curr_par1_t1 + lamb2*neuro_curr_par2_t1 + lamb3*neuro_curr_par3_t1 # Measurement model T1neuro_t2 =~ 1*neuro_curr_par1_t2 + lamb2*neuro_curr_par2_t2 + lamb3*neuro_curr_par3_t2 # Measurement model T2 with the equality constrained factor loadingsneuro_t2 ~ 1*neuro_t1 # This parameter regresses neuro_t2 perfectly on neuro_t1d_neuro_1 =~ 1*neuro_t2 # This defines the latent change score factor as measured perfectly by scores on neuro_t2neuro_t2 ~ 0*1 # This line constrains the intercept of neuro_t2 to 0neuro_t2 ~~ 0*neuro_t2 # This fixes the variance of neuro_t2 to 0d_neuro_1 ~ 1 # This estimates the intercept of the change score neuro_t1 ~ 1 # This estimates the intercept of neuro_t1 d_neuro_1 ~~ d_neuro_1 # This estimates the variance of the change scores neuro_t1 ~~ neuro_t1 # This estimates the variance of the neuro_t1 d_neuro_1 ~~ neuro_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change score remains unconditionalneuro_curr_par1_t1 ~~ neuro_curr_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2neuro_curr_par2_t1 ~~ neuro_curr_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2neuro_curr_par3_t1 ~~ neuro_curr_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2neuro_curr_par1_t1 ~~ res1*neuro_curr_par1_t1 # This allows residual variance on indicator X1 at T1 neuro_curr_par2_t1 ~~ res2*neuro_curr_par2_t1 # This allows residual variance on indicator X2 at T1neuro_curr_par3_t1 ~~ res3*neuro_curr_par3_t1 # This allows residual variance on indicator X3 at T1neuro_curr_par1_t2 ~~ res1*neuro_curr_par1_t2 # This allows residual variance on indicator X1 at T2 neuro_curr_par2_t2 ~~ res2*neuro_curr_par2_t2 # This allows residual variance on indicator X2 at T2 neuro_curr_par3_t2 ~~ res3*neuro_curr_par3_t2 # This allows residual variance on indicator X3 at T2neuro_curr_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1neuro_curr_par2_t1 ~ m2*1 # This estimates the intercept of X2 at T1neuro_curr_par3_t1 ~ m3*1 # This estimates the intercept of X3 at T1neuro_curr_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2neuro_curr_par2_t2 ~ m2*1 # This estimates the intercept of X2 at T2neuro_curr_par3_t2 ~ m3*1 # This estimates the intercept of X3 at T2'fit_mi_lcs_neuro_hyp2 <-lavaan(mi_lcs_neuro_hyp2, data=df_sbsa3_wide_pers, estimator='mlr', fixed.x=FALSE, missing='fiml')summary(fit_mi_lcs_neuro_hyp2, fit.measures=TRUE, standardized=TRUE, rsquare=F)
Significantly lower neuroticism at the post test, b = -0.053, beta = -0.167, p = 0.005.
6.4.5 Openness
Fit model:
Show the code
# Fit the multiple indicator Univariate Latent Change Score modelmi_lcs_openn_hyp2 <-'openn_t1 =~ 1*openn_curr_par1_t1 + lamb2*openn_curr_par2_t1 + lamb3*openn_curr_par3_t1 # Measurement model T1openn_t2 =~ 1*openn_curr_par1_t2 + lamb2*openn_curr_par2_t2 + lamb3*openn_curr_par3_t2 # Measurement model T2 with the equality constrained factor loadingsopenn_t2 ~ 1*openn_t1 # This parameter regresses openn_t2 perfectly on openn_t1d_openn_1 =~ 1*openn_t2 # This defines the latent change score factor as measured perfectly by scores on openn_t2openn_t2 ~ 0*1 # This line constrains the intercept of openn_t2 to 0openn_t2 ~~ 0*openn_t2 # This fixes the variance of openn_t2 to 0d_openn_1 ~ 1 # This estimates the intercept of the change score openn_t1 ~ 1 # This estimates the intercept of openn_t1 d_openn_1 ~~ d_openn_1 # This estimates the variance of the change scores openn_t1 ~~ openn_t1 # This estimates the variance of the openn_t1 d_openn_1 ~~ openn_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change score remains unconditionalopenn_curr_par1_t1 ~~ openn_curr_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2openn_curr_par2_t1 ~~ openn_curr_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2openn_curr_par3_t1 ~~ openn_curr_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2openn_curr_par1_t1 ~~ res1*openn_curr_par1_t1 # This allows residual variance on indicator X1 at T1 openn_curr_par2_t1 ~~ res2*openn_curr_par2_t1 # This allows residual variance on indicator X2 at T1openn_curr_par3_t1 ~~ res3*openn_curr_par3_t1 # This allows residual variance on indicator X3 at T1openn_curr_par1_t2 ~~ res1*openn_curr_par1_t2 # This allows residual variance on indicator X1 at T2 openn_curr_par2_t2 ~~ res2*openn_curr_par2_t2 # This allows residual variance on indicator X2 at T2 openn_curr_par3_t2 ~~ res3*openn_curr_par3_t2 # This allows residual variance on indicator X3 at T2openn_curr_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1openn_curr_par2_t1 ~ m2*1 # This estimates the intercept of X2 at T1openn_curr_par3_t1 ~ m3*1 # This estimates the intercept of X3 at T1openn_curr_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2openn_curr_par2_t2 ~ m2*1 # This estimates the intercept of X2 at T2openn_curr_par3_t2 ~ m3*1 # This estimates the intercept of X3 at T2'fit_mi_lcs_openn_hyp2 <-lavaan(mi_lcs_openn_hyp2, data=df_sbsa3_wide_pers, estimator='mlr', fixed.x=FALSE, missing='fiml')summary(fit_mi_lcs_openn_hyp2, fit.measures=TRUE, standardized=TRUE, rsquare=F)
No significant changes in openness from pre to post test, b = 0.019, beta = 0.117, p = 0.155.
7 Differences in change across groups (SEM)
We will explore a) whether change in psychological well-being indicators as well as the difference between real- and ideal- self will differ across groups at follow-up.
7.1 Group 1 vs. Group 2: Effect of discrepancy awareness
7.1.1 Well-being change: differences across groups
7.1.1.1 Life satisfaction
Life satisfaction: fitting multi-group models
Show the code
# adapt latent change score model from above and add grouping factor in estimation (also add vectorized equality constraints to the model)# configural invariancemi_lcs_swls_group_config <-'swls_t1 =~ 1*sw06_01_t1 + c("lamb2a", "lamb2b")*sw06_02_t1 + c("lamb3a", "lamb3b")*sw06_03_t1 + c("lamb4a", "lamb4b")*sw06_04_t1 # This specifies the measurement model for swls_t1 swls_t2 =~ 1*sw06_01_t2 + c("lamb2a", "lamb2b")*sw06_02_t2 + c("lamb3a", "lamb3b")*sw06_03_t2 + c("lamb4a", "lamb4b")*sw06_04_t2 # This specifies the measurement model for swls_t2 with the equality constrained factor loadingsswls_t2 ~ 1*swls_t1 # This parameter regresses swls_t2 perfectly on swls_t1d_swls_1 =~ 1*swls_t2 # This defines the latent change score factor as measured perfectly by scores on swls_t2swls_t2 ~ 0*1 # This line constrains the intercept of swls_t2 to 0swls_t2 ~~ 0*swls_t2 # This fixes the variance of swls_t2 to 0d_swls_1 ~ c("d_int_a", "d_int_b")*1 # This estimates the intercept of the change score swls_t1 ~ c("wb_int_a", "wb_int_b")*1 # This estimates the intercept of swls_t1 d_swls_1 ~~ c("d_var_a", "d_var_b")*d_swls_1 # This estimates the variance of the change scores swls_t1 ~~ c("wb_var_a", "wb_var_b")*swls_t1 # This estimates the variance of the swls_t1 d_swls_1 ~~ c("fb_a", "fb_b")*swls_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change score remains unconditionalsw06_01_t1 ~~ c("cov1a", "cov1b")*sw06_01_t2 # This allows residual covariance on indicator X1 across T1 and T2sw06_02_t1 ~~ c("cov2a", "cov2b")*sw06_02_t2 # This allows residual covariance on indicator X2 across T1 and T2sw06_03_t1 ~~ c("cov3a", "cov3b")*sw06_03_t2 # This allows residual covariance on indicator X3 across T1 and T2sw06_04_t1 ~~ c("cov4a", "cov4b")*sw06_04_t2 # This allows residual covariance on indicator X4 across T1 and T2sw06_01_t1 ~~ c("res1a", "res1b")*sw06_01_t1 # This allows residual variance on indicator X1 at T1 sw06_02_t1 ~~ c("res2a", "res2b")*sw06_02_t1 # This allows residual variance on indicator X2 at T1sw06_03_t1 ~~ c("res3a", "res3b")*sw06_03_t1 # This allows residual variance on indicator X3 at T1sw06_04_t1 ~~ c("res4a", "res4b")*sw06_04_t1 # This allows residual variance on indicator X4 at T1sw06_01_t2 ~~ c("res1a", "res1b")*sw06_01_t2 # This allows residual variance on indicator X1 at T2 sw06_02_t2 ~~ c("res2a", "res2b")*sw06_02_t2 # This allows residual variance on indicator X2 at T2 sw06_03_t2 ~~ c("res3a", "res3b")*sw06_03_t2 # This allows residual variance on indicator X3 at T2sw06_04_t2 ~~ c("res4a", "res4b")*sw06_04_t2 # This allows residual variance on indicator X4 at T2sw06_01_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1sw06_02_t1 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T1sw06_03_t1 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T1sw06_04_t1 ~ c("m4a", "m4b")*1 # This estimates the intercept of X4 at T1sw06_01_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2sw06_02_t2 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T2sw06_03_t2 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T2sw06_04_t2 ~ c("m4a", "m4b")*1 # This estimates the intercept of X4 at T2'lcs_swls_group_12_config <-sem(mi_lcs_swls_group_config, data=df_sbsa3_wide_wb %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group")# weak invariancemi_lcs_swls_group_weak <-'swls_t1 =~ 1*sw06_01_t1 + c("lamb2", "lamb2")*sw06_02_t1 + c("lamb3", "lamb3")*sw06_03_t1 + c("lamb4", "lamb4")*sw06_04_t1 # This specifies the measurement model for swls_t1 swls_t2 =~ 1*sw06_01_t2 + c("lamb2", "lamb2")*sw06_02_t2 + c("lamb3", "lamb3")*sw06_03_t2 + c("lamb4", "lamb4")*sw06_04_t2 # This specifies the measurement model for swls_t2 with the equality constrained factor loadingsswls_t2 ~ 1*swls_t1 # This parameter regresses swls_t2 perfectly on swls_t1d_swls_1 =~ 1*swls_t2 # This defines the latent change score factor as measured perfectly by scores on swls_t2swls_t2 ~ 0*1 # This line constrains the intercept of swls_t2 to 0swls_t2 ~~ 0*swls_t2 # This fixes the variance of swls_t2 to 0d_swls_1 ~ c("d_int_a", "d_int_b")*1 # This estimates the intercept of the change score swls_t1 ~ c("wb_int_a", "wb_int_b")*1 # This estimates the intercept of swls_t1 d_swls_1 ~~ c("d_var_a", "d_var_b")*d_swls_1 # This estimates the variance of the change scores swls_t1 ~~ c("wb_var_a", "wb_var_b")*swls_t1 # This estimates the variance of the swls_t1 d_swls_1 ~~ c("fb_a", "fb_b")*swls_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change scoresw06_01_t1 ~~ c("cov1a", "cov1b")*sw06_01_t2 # This allows residual covariance on indicator X1 across T1 and T2sw06_02_t1 ~~ c("cov2a", "cov2b")*sw06_02_t2 # This allows residual covariance on indicator X2 across T1 and T2sw06_03_t1 ~~ c("cov3a", "cov3b")*sw06_03_t2 # This allows residual covariance on indicator X3 across T1 and T2sw06_04_t1 ~~ c("cov4a", "cov4b")*sw06_04_t2 # This allows residual covariance on indicator X4 across T1 and T2sw06_01_t1 ~~ c("res1a", "res1b")*sw06_01_t1 # This allows residual variance on indicator X1 at T1 sw06_02_t1 ~~ c("res2a", "res2b")*sw06_02_t1 # This allows residual variance on indicator X2 at T1sw06_03_t1 ~~ c("res3a", "res3b")*sw06_03_t1 # This allows residual variance on indicator X3 at T1sw06_04_t1 ~~ c("res4a", "res4b")*sw06_04_t1 # This allows residual variance on indicator X4 at T1sw06_01_t2 ~~ c("res1a", "res1b")*sw06_01_t2 # This allows residual variance on indicator X1 at T2 sw06_02_t2 ~~ c("res2a", "res2b")*sw06_02_t2 # This allows residual variance on indicator X2 at T2 sw06_03_t2 ~~ c("res3a", "res3b")*sw06_03_t2 # This allows residual variance on indicator X3 at T2sw06_04_t2 ~~ c("res4a", "res4b")*sw06_04_t2 # This allows residual variance on indicator X4 at T2sw06_01_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1sw06_02_t1 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T1sw06_03_t1 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T1sw06_04_t1 ~ c("m4a", "m4b")*1 # This estimates the intercept of X4 at T1sw06_01_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2sw06_02_t2 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T2sw06_03_t2 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T2sw06_04_t2 ~ c("m4a", "m4b")*1 # This estimates the intercept of X4 at T2'lcs_swls_group_12_weak <-sem(mi_lcs_swls_group_weak, data=df_sbsa3_wide_wb %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal ="loadings")# strong invariancemi_lcs_swls_group_strong <-'swls_t1 =~ 1*sw06_01_t1 + c("lamb2", "lamb2")*sw06_02_t1 + c("lamb3", "lamb3")*sw06_03_t1 + c("lamb4", "lamb4")*sw06_04_t1 # This specifies the measurement model for swls_t1 swls_t2 =~ 1*sw06_01_t2 + c("lamb2", "lamb2")*sw06_02_t2 + c("lamb3", "lamb3")*sw06_03_t2 + c("lamb4", "lamb4")*sw06_04_t2 # This specifies the measurement model for swls_t2 with the equality constrained factor loadingsswls_t2 ~ 1*swls_t1 # This parameter regresses swls_t2 perfectly on swls_t1d_swls_1 =~ 1*swls_t2 # This defines the latent change score factor as measured perfectly by scores on swls_t2swls_t2 ~ 0*1 # This line constrains the intercept of swls_t2 to 0swls_t2 ~~ 0*swls_t2 # This fixes the variance of swls_t2 to 0d_swls_1 ~ c("d_int", "d_int")*1 # This estimates the intercept of the change score swls_t1 ~ c("wb_int", "wb_int")*1 # This estimates the intercept of swls_t1 d_swls_1 ~~ c("d_var_a", "d_var_b")*d_swls_1 # This estimates the variance of the change scores swls_t1 ~~ c("wb_var_a", "wb_var_b")*swls_t1 # This estimates the variance of the swls_t1 d_swls_1 ~~ c("fb_a", "fb_b")*swls_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change scoresw06_01_t1 ~~ c("cov1a", "cov1b")*sw06_01_t2 # This allows residual covariance on indicator X1 across T1 and T2sw06_02_t1 ~~ c("cov2a", "cov2b")*sw06_02_t2 # This allows residual covariance on indicator X2 across T1 and T2sw06_03_t1 ~~ c("cov3a", "cov3b")*sw06_03_t2 # This allows residual covariance on indicator X3 across T1 and T2sw06_04_t1 ~~ c("cov4a", "cov4b")*sw06_04_t2 # This allows residual covariance on indicator X4 across T1 and T2sw06_01_t1 ~~ c("res1a", "res1b")*sw06_01_t1 # This allows residual variance on indicator X1 at T1 sw06_02_t1 ~~ c("res2a", "res2b")*sw06_02_t1 # This allows residual variance on indicator X2 at T1sw06_03_t1 ~~ c("res3a", "res3b")*sw06_03_t1 # This allows residual variance on indicator X3 at T1sw06_04_t1 ~~ c("res4a", "res4b")*sw06_04_t1 # This allows residual variance on indicator X4 at T1sw06_01_t2 ~~ c("res1a", "res1b")*sw06_01_t2 # This allows residual variance on indicator X1 at T2 sw06_02_t2 ~~ c("res2a", "res2b")*sw06_02_t2 # This allows residual variance on indicator X2 at T2 sw06_03_t2 ~~ c("res3a", "res3b")*sw06_03_t2 # This allows residual variance on indicator X3 at T2sw06_04_t2 ~~ c("res4a", "res4b")*sw06_04_t2 # This allows residual variance on indicator X4 at T2sw06_01_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1sw06_02_t1 ~ c("m2", "m2")*1 # This estimates the intercept of X2 at T1sw06_03_t1 ~ c("m3", "m3")*1 # This estimates the intercept of X3 at T1sw06_04_t1 ~ c("m4", "m4")*1 # This estimates the intercept of X4 at T1sw06_01_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2sw06_02_t2 ~ c("m2", "m2")*1 # This estimates the intercept of X2 at T2sw06_03_t2 ~ c("m3", "m3")*1 # This estimates the intercept of X3 at T2sw06_04_t2 ~ c("m4", "m4")*1 # This estimates the intercept of X4 at T2'lcs_swls_group_12_strong <-sem(mi_lcs_swls_group_strong, data=df_sbsa3_wide_wb %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal =c("intercepts", "loadings"))
Life satisfaction: results
# model comparison tests for measurement invariancelavTestLRT(lcs_swls_group_12_config, lcs_swls_group_12_weak, lcs_swls_group_12_strong)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff Pr(>Chisq)
lcs_swls_group_12_config 50 6867.5 7014.6 94.812
lcs_swls_group_12_weak 53 6865.6 7001.0 98.864 4.2444 3 0.2363
lcs_swls_group_12_strong 58 6862.7 6978.8 106.007 7.1600 5 0.2090
# show model with varying latent change parameters # -> key parameter is "d_swls_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 1, b = Group 2)params_lcs_swls_group_12_weak <- broom::tidy(lcs_swls_group_12_weak, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_swls_1 ~1 ")) %>%mutate(sig_diff =" ")kable(params_lcs_swls_group_12_weak, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_swls_1 ~1
d_int_a
0.187
0.317
3.237
0.001
d_swls_1 ~1
d_int_b
0.259
0.512
4.843
0.000
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(lcs_swls_group_12_strong, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_swls_1 ~1 ")), digits =3)
term
label
estimate
std.all
statistic
p.value
d_swls_1 ~1
d_int
0.228
0.385
5.83
0
d_swls_1 ~1
d_int
0.228
0.448
5.83
0
Slightly more positive change in life satisfaction in Group 2 compared to Group 1 but no substantial differences according to the LRTs.
# whole model (weak invariance)summary(lcs_swls_group_12_weak, fit.measures=TRUE, standardized=TRUE, rsquare=F)
# adapt latent change score model from above and add grouping factor in estimation (also add vectorized equality constraints to the model)# configural invariancemi_lcs_meaning_group_config <-'meaning_t1 =~ 1*meaning_par1_t1 + c("lamb2a", "lamb2b")*meaning_par2_t1 + c("lamb3a", "lamb3b")*meaning_par3_t1 # This specifies the measurement model for meaning_t1 meaning_t2 =~ 1*meaning_par1_t2 + c("lamb2a", "lamb2b")*meaning_par2_t2 + c("lamb3a", "lamb3b")*meaning_par3_t2 # This specifies the measurement model for meaning_t2 with the equality constrained factor loadingsmeaning_t2 ~ 1*meaning_t1 # This parameter regresses meaning_t2 perfectly on meaning_t1d_meaning_1 =~ 1*meaning_t2 # This defines the latent change score factor as measured perfectly by scores on meaning_t2meaning_t2 ~ 0*1 # This line constrains the intercept of meaning_t2 to 0meaning_t2 ~~ 0*meaning_t2 # This fixes the variance of meaning_t2 to 0d_meaning_1 ~ c("d_int_a", "d_int_b")*1 # This estimates the intercept of the change score meaning_t1 ~ c("wb_int_a", "wb_int_b")*1 # This estimates the intercept of meaning_t1 d_meaning_1 ~~ c("d_var_a", "d_var_b")*d_meaning_1 # This estimates the variance of the change scores meaning_t1 ~~ c("wb_var_a", "wb_var_b")*meaning_t1 # This estimates the variance of the meaning_t1 d_meaning_1 ~~ c("fb_a", "fb_b")*meaning_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change scoremeaning_par1_t1 ~~ c("cov1a", "cov1b")*meaning_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2meaning_par2_t1 ~~ c("cov2a", "cov2b")*meaning_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2meaning_par3_t1 ~~ c("cov3a", "cov3b")*meaning_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2meaning_par1_t1 ~~ c("res1a", "res1b")*meaning_par1_t1 # This allows residual variance on indicator X1 at T1 meaning_par2_t1 ~~ c("res2a", "res2b")*meaning_par2_t1 # This allows residual variance on indicator X2 at T1meaning_par3_t1 ~~ c("res3a", "res3b")*meaning_par3_t1 # This allows residual variance on indicator X3 at T1meaning_par1_t2 ~~ c("res1a", "res1b")*meaning_par1_t2 # This allows residual variance on indicator X1 at T2 meaning_par2_t2 ~~ c("res2a", "res2b")*meaning_par2_t2 # This allows residual variance on indicator X2 at T2 meaning_par3_t2 ~~ c("res3a", "res3b")*meaning_par3_t2 # This allows residual variance on indicator X3 at T2meaning_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1meaning_par2_t1 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T1meaning_par3_t1 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T1meaning_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2meaning_par2_t2 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T2meaning_par3_t2 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T2'lcs_meaning_group_12_config <-sem(mi_lcs_meaning_group_config, data=df_sbsa3_wide_wb %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group")# weak invariancemi_lcs_meaning_group_weak <-'meaning_t1 =~ 1*meaning_par1_t1 + c("lamb2", "lamb2")*meaning_par2_t1 + c("lamb3", "lamb3")*meaning_par3_t1 # This specifies the measurement model for meaning_t1 meaning_t2 =~ 1*meaning_par1_t2 + c("lamb2", "lamb2")*meaning_par2_t2 + c("lamb3", "lamb3")*meaning_par3_t2 # This specifies the measurement model for meaning_t2 with the equality constrained factor loadingsmeaning_t2 ~ 1*meaning_t1 # This parameter regresses meaning_t2 perfectly on meaning_t1d_meaning_1 =~ 1*meaning_t2 # This defines the latent change score factor as measured perfectly by scores on meaning_t2meaning_t2 ~ 0*1 # This line constrains the intercept of meaning_t2 to 0meaning_t2 ~~ 0*meaning_t2 # This fixes the variance of meaning_t2 to 0d_meaning_1 ~ c("d_int_a", "d_int_b")*1 # This estimates the intercept of the change score meaning_t1 ~ c("wb_int_a", "wb_int_b")*1 # This estimates the intercept of meaning_t1 d_meaning_1 ~~ c("d_var_a", "d_var_b")*d_meaning_1 # This estimates the variance of the change scores meaning_t1 ~~ c("wb_var_a", "wb_var_b")*meaning_t1 # This estimates the variance of the meaning_t1 d_meaning_1 ~~ c("fb_a", "fb_b")*meaning_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change scoremeaning_par1_t1 ~~ c("cov1a", "cov1b")*meaning_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2meaning_par2_t1 ~~ c("cov2a", "cov2b")*meaning_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2meaning_par3_t1 ~~ c("cov3a", "cov3b")*meaning_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2meaning_par1_t1 ~~ c("res1a", "res1b")*meaning_par1_t1 # This allows residual variance on indicator X1 at T1 meaning_par2_t1 ~~ c("res2a", "res2b")*meaning_par2_t1 # This allows residual variance on indicator X2 at T1meaning_par3_t1 ~~ c("res3a", "res3b")*meaning_par3_t1 # This allows residual variance on indicator X3 at T1meaning_par1_t2 ~~ c("res1a", "res1b")*meaning_par1_t2 # This allows residual variance on indicator X1 at T2 meaning_par2_t2 ~~ c("res2a", "res2b")*meaning_par2_t2 # This allows residual variance on indicator X2 at T2 meaning_par3_t2 ~~ c("res3a", "res3b")*meaning_par3_t2 # This allows residual variance on indicator X3 at T2meaning_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1meaning_par2_t1 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T1meaning_par3_t1 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T1meaning_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2meaning_par2_t2 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T2meaning_par3_t2 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T2'lcs_meaning_group_12_weak <-sem(mi_lcs_meaning_group_weak, data=df_sbsa3_wide_wb %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal ="loadings")# strong invariancemi_lcs_meaning_group_strong <-'meaning_t1 =~ 1*meaning_par1_t1 + c("lamb2", "lamb2")*meaning_par2_t1 + c("lamb3", "lamb3")*meaning_par3_t1 # This specifies the measurement model for meaning_t1 meaning_t2 =~ 1*meaning_par1_t2 + c("lamb2", "lamb2")*meaning_par2_t2 + c("lamb3", "lamb3")*meaning_par3_t2 # This specifies the measurement model for meaning_t2 with the equality constrained factor loadingsmeaning_t2 ~ 1*meaning_t1 # This parameter regresses meaning_t2 perfectly on meaning_t1d_meaning_1 =~ 1*meaning_t2 # This defines the latent change score factor as measured perfectly by scores on meaning_t2meaning_t2 ~ 0*1 # This line constrains the intercept of meaning_t2 to 0meaning_t2 ~~ 0*meaning_t2 # This fixes the variance of meaning_t2 to 0d_meaning_1 ~ c("d_int", "d_int")*1 # This estimates the intercept of the change score meaning_t1 ~ c("wb_int", "wb_int")*1 # This estimates the intercept of meaning_t1 d_meaning_1 ~~ c("d_var_a", "d_var_b")*d_meaning_1 # This estimates the variance of the change scores meaning_t1 ~~ c("wb_var_a", "wb_var_b")*meaning_t1 # This estimates the variance of the meaning_t1 d_meaning_1 ~~ c("fb_a", "fb_b")*meaning_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change scoremeaning_par1_t1 ~~ c("cov1a", "cov1b")*meaning_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2meaning_par2_t1 ~~ c("cov2a", "cov2b")*meaning_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2meaning_par3_t1 ~~ c("cov3a", "cov3b")*meaning_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2meaning_par1_t1 ~~ c("res1a", "res1b")*meaning_par1_t1 # This allows residual variance on indicator X1 at T1 meaning_par2_t1 ~~ c("res2a", "res2b")*meaning_par2_t1 # This allows residual variance on indicator X2 at T1meaning_par3_t1 ~~ c("res3a", "res3b")*meaning_par3_t1 # This allows residual variance on indicator X3 at T1meaning_par1_t2 ~~ c("res1a", "res1b")*meaning_par1_t2 # This allows residual variance on indicator X1 at T2 meaning_par2_t2 ~~ c("res2a", "res2b")*meaning_par2_t2 # This allows residual variance on indicator X2 at T2 meaning_par3_t2 ~~ c("res3a", "res3b")*meaning_par3_t2 # This allows residual variance on indicator X3 at T2meaning_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1meaning_par2_t1 ~ c("m2", "m2")*1 # This estimates the intercept of X2 at T1meaning_par3_t1 ~ c("m3", "m3")*1 # This estimates the intercept of X3 at T1meaning_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2meaning_par2_t2 ~ c("m2", "m2")*1 # This estimates the intercept of X2 at T2meaning_par3_t2 ~ c("m3", "m3")*1 # This estimates the intercept of X3 at T2'lcs_meaning_group_12_strong <-sem(mi_lcs_meaning_group_strong, data=df_sbsa3_wide_wb %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal =c("intercepts", "loadings"))
Meaning in life: results
# model comparison tests for measurement invariancelavTestLRT(lcs_meaning_group_12_config, lcs_meaning_group_12_weak, lcs_meaning_group_12_strong)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
lcs_meaning_group_12_config 24 5087.3 5203.4 22.780
lcs_meaning_group_12_weak 26 5087.8 5196.2 27.304 4.7694 2
lcs_meaning_group_12_strong 30 5084.2 5177.1 31.705 4.3666 4
Pr(>Chisq)
lcs_meaning_group_12_config
lcs_meaning_group_12_weak 0.09212 .
lcs_meaning_group_12_strong 0.35867
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# show model with varying latent change parameters # -> key parameter is "d_meaning_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 1, b = Group 2)params_lcs_meaning_group_12_weak <- broom::tidy(lcs_meaning_group_12_weak, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_meaning_1 ~1 ")) %>%mutate(sig_diff =" ")kable(params_lcs_meaning_group_12_weak, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_meaning_1 ~1
d_int_a
0.105
0.186
1.961
0.050
d_meaning_1 ~1
d_int_b
0.113
0.200
2.031
0.042
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(lcs_meaning_group_12_strong, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_meaning_1 ~1 ")), digits =3)
term
label
estimate
std.all
statistic
p.value
d_meaning_1 ~1
d_int
0.109
0.193
2.776
0.005
d_meaning_1 ~1
d_int
0.109
0.194
2.776
0.005
Very similar degree of positive change in meaning in life in both groups and no substantial differences according to the LRTs.
# whole model (weak invariance)summary(lcs_meaning_group_12_weak, fit.measures=TRUE, standardized=TRUE, rsquare=F)
# adapt latent change score model from above and add grouping factor in estimation (also add vectorized equality constraints to the model)# configural invariancemi_lcs_selfes_group_config <-'selfes_t1 =~ 1*selfes_par1_t1 + c("lamb2a", "lamb2b")*selfes_par2_t1 + c("lamb3a", "lamb3b")*selfes_par3_t1 # This specifies the measurement model for selfes_t1 selfes_t2 =~ 1*selfes_par1_t2 + c("lamb2a", "lamb2b")*selfes_par2_t2 + c("lamb3a", "lamb3b")*selfes_par3_t2 # This specifies the measurement model for selfes_t2 with the equality constrained factor loadingsselfes_t2 ~ 1*selfes_t1 # This parameter regresses selfes_t2 perfectly on selfes_t1d_selfes_1 =~ 1*selfes_t2 # This defines the latent change score factor as measured perfectly by scores on selfes_t2selfes_t2 ~ 0*1 # This line constrains the intercept of selfes_t2 to 0selfes_t2 ~~ 0*selfes_t2 # This fixes the variance of selfes_t2 to 0d_selfes_1 ~ c("d_int_a", "d_int_b")*1 # This estimates the intercept of the change score selfes_t1 ~ c("wb_int_a", "wb_int_b")*1 # This estimates the intercept of selfes_t1 d_selfes_1 ~~ c("d_var_a", "d_var_b")*d_selfes_1 # This estimates the variance of the change scores selfes_t1 ~~ c("wb_var_a", "wb_var_b")*selfes_t1 # This estimates the variance of the selfes_t1 d_selfes_1 ~~ c("fb_a", "fb_b")*selfes_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change scoreselfes_par1_t1 ~~ c("cov1a", "cov1b")*selfes_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2selfes_par2_t1 ~~ c("cov2a", "cov2b")*selfes_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2selfes_par3_t1 ~~ c("cov3a", "cov3b")*selfes_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2selfes_par1_t1 ~~ c("res1a", "res1b")*selfes_par1_t1 # This allows residual variance on indicator X1 at T1 selfes_par2_t1 ~~ c("res2a", "res2b")*selfes_par2_t1 # This allows residual variance on indicator X2 at T1selfes_par3_t1 ~~ c("res3a", "res3b")*selfes_par3_t1 # This allows residual variance on indicator X3 at T1selfes_par1_t2 ~~ c("res1a", "res1b")*selfes_par1_t2 # This allows residual variance on indicator X1 at T2 selfes_par2_t2 ~~ c("res2a", "res2b")*selfes_par2_t2 # This allows residual variance on indicator X2 at T2 selfes_par3_t2 ~~ c("res3a", "res3b")*selfes_par3_t2 # This allows residual variance on indicator X3 at T2selfes_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1selfes_par2_t1 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T1selfes_par3_t1 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T1selfes_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2selfes_par2_t2 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T2selfes_par3_t2 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T2'lcs_selfes_group_12_config <-sem(mi_lcs_selfes_group_config, data=df_sbsa3_wide_wb %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group")# weak invariancemi_lcs_selfes_group_weak <-'selfes_t1 =~ 1*selfes_par1_t1 + c("lamb2", "lamb2")*selfes_par2_t1 + c("lamb3", "lamb3")*selfes_par3_t1 # This specifies the measurement model for selfes_t1 selfes_t2 =~ 1*selfes_par1_t2 + c("lamb2", "lamb2")*selfes_par2_t2 + c("lamb3", "lamb3")*selfes_par3_t2 # This specifies the measurement model for selfes_t2 with the equality constrained factor loadingsselfes_t2 ~ 1*selfes_t1 # This parameter regresses selfes_t2 perfectly on selfes_t1d_selfes_1 =~ 1*selfes_t2 # This defines the latent change score factor as measured perfectly by scores on selfes_t2selfes_t2 ~ 0*1 # This line constrains the intercept of selfes_t2 to 0selfes_t2 ~~ 0*selfes_t2 # This fixes the variance of selfes_t2 to 0d_selfes_1 ~ c("d_int_a", "d_int_b")*1 # This estimates the intercept of the change score selfes_t1 ~ c("wb_int_a", "wb_int_b")*1 # This estimates the intercept of selfes_t1 d_selfes_1 ~~ c("d_var_a", "d_var_b")*d_selfes_1 # This estimates the variance of the change scores selfes_t1 ~~ c("wb_var_a", "wb_var_b")*selfes_t1 # This estimates the variance of the selfes_t1 d_selfes_1 ~~ c("fb_a", "fb_b")*selfes_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change scoreselfes_par1_t1 ~~ c("cov1a", "cov1b")*selfes_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2selfes_par2_t1 ~~ c("cov2a", "cov2b")*selfes_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2selfes_par3_t1 ~~ c("cov3a", "cov3b")*selfes_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2selfes_par1_t1 ~~ c("res1a", "res1b")*selfes_par1_t1 # This allows residual variance on indicator X1 at T1 selfes_par2_t1 ~~ c("res2a", "res2b")*selfes_par2_t1 # This allows residual variance on indicator X2 at T1selfes_par3_t1 ~~ c("res3a", "res3b")*selfes_par3_t1 # This allows residual variance on indicator X3 at T1selfes_par1_t2 ~~ c("res1a", "res1b")*selfes_par1_t2 # This allows residual variance on indicator X1 at T2 selfes_par2_t2 ~~ c("res2a", "res2b")*selfes_par2_t2 # This allows residual variance on indicator X2 at T2 selfes_par3_t2 ~~ c("res3a", "res3b")*selfes_par3_t2 # This allows residual variance on indicator X3 at T2selfes_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1selfes_par2_t1 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T1selfes_par3_t1 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T1selfes_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2selfes_par2_t2 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T2selfes_par3_t2 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T2'lcs_selfes_group_12_weak <-sem(mi_lcs_selfes_group_weak, data=df_sbsa3_wide_wb %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal ="loadings")# strong invariancemi_lcs_selfes_group_strong <-'selfes_t1 =~ 1*selfes_par1_t1 + c("lamb2", "lamb2")*selfes_par2_t1 + c("lamb3", "lamb3")*selfes_par3_t1 # This specifies the measurement model for selfes_t1 selfes_t2 =~ 1*selfes_par1_t2 + c("lamb2", "lamb2")*selfes_par2_t2 + c("lamb3", "lamb3")*selfes_par3_t2 # This specifies the measurement model for selfes_t2 with the equality constrained factor loadingsselfes_t2 ~ 1*selfes_t1 # This parameter regresses selfes_t2 perfectly on selfes_t1d_selfes_1 =~ 1*selfes_t2 # This defines the latent change score factor as measured perfectly by scores on selfes_t2selfes_t2 ~ 0*1 # This line constrains the intercept of selfes_t2 to 0selfes_t2 ~~ 0*selfes_t2 # This fixes the variance of selfes_t2 to 0d_selfes_1 ~ c("d_int", "d_int")*1 # This estimates the intercept of the change score selfes_t1 ~ c("wb_int", "wb_int")*1 # This estimates the intercept of selfes_t1 d_selfes_1 ~~ c("d_var_a", "d_var_b")*d_selfes_1 # This estimates the variance of the change scores selfes_t1 ~~ c("wb_var_a", "wb_var_b")*selfes_t1 # This estimates the variance of the selfes_t1 d_selfes_1 ~~ c("fb_a", "fb_b")*selfes_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change scoreselfes_par1_t1 ~~ c("cov1a", "cov1b")*selfes_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2selfes_par2_t1 ~~ c("cov2a", "cov2b")*selfes_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2selfes_par3_t1 ~~ c("cov3a", "cov3b")*selfes_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2selfes_par1_t1 ~~ c("res1a", "res1b")*selfes_par1_t1 # This allows residual variance on indicator X1 at T1 selfes_par2_t1 ~~ c("res2a", "res2b")*selfes_par2_t1 # This allows residual variance on indicator X2 at T1selfes_par3_t1 ~~ c("res3a", "res3b")*selfes_par3_t1 # This allows residual variance on indicator X3 at T1selfes_par1_t2 ~~ c("res1a", "res1b")*selfes_par1_t2 # This allows residual variance on indicator X1 at T2 selfes_par2_t2 ~~ c("res2a", "res2b")*selfes_par2_t2 # This allows residual variance on indicator X2 at T2 selfes_par3_t2 ~~ c("res3a", "res3b")*selfes_par3_t2 # This allows residual variance on indicator X3 at T2selfes_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1selfes_par2_t1 ~ c("m2", "m2")*1 # This estimates the intercept of X2 at T1selfes_par3_t1 ~ c("m3", "m3")*1 # This estimates the intercept of X3 at T1selfes_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2selfes_par2_t2 ~ c("m2", "m2")*1 # This estimates the intercept of X2 at T2selfes_par3_t2 ~ c("m3", "m3")*1 # This estimates the intercept of X3 at T2'lcs_selfes_group_12_strong <-sem(mi_lcs_selfes_group_strong, data=df_sbsa3_wide_wb %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal =c("intercepts", "loadings"))
Meaning in life: results
# model comparison tests for measurement invariancelavTestLRT(lcs_selfes_group_12_config, lcs_selfes_group_12_weak, lcs_selfes_group_12_strong)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
lcs_selfes_group_12_config 24 3696.0 3812.1 19.460
lcs_selfes_group_12_weak 26 3692.2 3800.5 19.616 0.1506 2
lcs_selfes_group_12_strong 30 3701.5 3794.3 36.898 16.7031 4
Pr(>Chisq)
lcs_selfes_group_12_config
lcs_selfes_group_12_weak 0.927464
lcs_selfes_group_12_strong 0.002207 **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# show model with varying latent change parameters # -> key parameter is "d_selfes_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 1, b = Group 2)params_lcs_selfes_group_12_weak <- broom::tidy(lcs_selfes_group_12_weak, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_selfes_1 ~1 ")) %>%mutate(sig_diff ="**")kable(params_lcs_selfes_group_12_weak, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_selfes_1 ~1
d_int_a
0.108
0.247
2.765
0.006
**
d_selfes_1 ~1
d_int_b
0.166
0.398
4.158
0.000
**
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(lcs_selfes_group_12_strong, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_selfes_1 ~1 ")), digits =3)
term
label
estimate
std.all
statistic
p.value
d_selfes_1 ~1
d_int
0.139
0.315
4.742
0
d_selfes_1 ~1
d_int
0.139
0.331
4.742
0
Significantly more positive change in self-esteem in Group 2 compared to Group 1.
# whole model (weak invariance)summary(lcs_selfes_group_12_weak, fit.measures=TRUE, standardized=TRUE, rsquare=F)
# adapt latent change score model from above and add grouping factor in estimation (also add vectorized equality constraints to the model)# configural invariancemi_lcs_concept_group_config <-'concept_t1 =~ 1*concept_par1_t1 + c("lamb2a", "lamb2b")*concept_par2_t1 + c("lamb3a", "lamb3b")*concept_par3_t1 # This specifies the measurement model for concept_t1 concept_t2 =~ 1*concept_par1_t2 + c("lamb2a", "lamb2b")*concept_par2_t2 + c("lamb3a", "lamb3b")*concept_par3_t2 # This specifies the measurement model for concept_t2 with the equality constrained factor loadingsconcept_t2 ~ 1*concept_t1 # This parameter regresses concept_t2 perfectly on concept_t1d_concept_1 =~ 1*concept_t2 # This defines the latent change score factor as measured perfectly by scores on concept_t2concept_t2 ~ 0*1 # This line constrains the intercept of concept_t2 to 0concept_t2 ~~ 0*concept_t2 # This fixes the variance of concept_t2 to 0d_concept_1 ~ c("d_int_a", "d_int_b")*1 # This estimates the intercept of the change score concept_t1 ~ c("wb_int_a", "wb_int_b")*1 # This estimates the intercept of concept_t1 d_concept_1 ~~ c("d_var_a", "d_var_b")*d_concept_1 # This estimates the variance of the change scores concept_t1 ~~ c("wb_var_a", "wb_var_b")*concept_t1 # This estimates the variance of the concept_t1 d_concept_1 ~~ c("fb_a", "fb_b")*concept_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change scoreconcept_par1_t1 ~~ c("cov1a", "cov1b")*concept_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2concept_par2_t1 ~~ c("cov2a", "cov2b")*concept_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2concept_par3_t1 ~~ c("cov3a", "cov3b")*concept_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2concept_par1_t1 ~~ c("res1a", "res1b")*concept_par1_t1 # This allows residual variance on indicator X1 at T1 concept_par2_t1 ~~ c("res2a", "res2b")*concept_par2_t1 # This allows residual variance on indicator X2 at T1concept_par3_t1 ~~ c("res3a", "res3b")*concept_par3_t1 # This allows residual variance on indicator X3 at T1concept_par1_t2 ~~ c("res1a", "res1b")*concept_par1_t2 # This allows residual variance on indicator X1 at T2 concept_par2_t2 ~~ c("res2a", "res2b")*concept_par2_t2 # This allows residual variance on indicator X2 at T2 concept_par3_t2 ~~ c("res3a", "res3b")*concept_par3_t2 # This allows residual variance on indicator X3 at T2concept_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1concept_par2_t1 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T1concept_par3_t1 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T1concept_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2concept_par2_t2 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T2concept_par3_t2 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T2'lcs_concept_group_12_config <-sem(mi_lcs_concept_group_config, data=df_sbsa3_wide_wb %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group")# weak invariancemi_lcs_concept_group_weak <-'concept_t1 =~ 1*concept_par1_t1 + c("lamb2", "lamb2")*concept_par2_t1 + c("lamb3", "lamb3")*concept_par3_t1 # This specifies the measurement model for concept_t1 concept_t2 =~ 1*concept_par1_t2 + c("lamb2", "lamb2")*concept_par2_t2 + c("lamb3", "lamb3")*concept_par3_t2 # This specifies the measurement model for concept_t2 with the equality constrained factor loadingsconcept_t2 ~ 1*concept_t1 # This parameter regresses concept_t2 perfectly on concept_t1d_concept_1 =~ 1*concept_t2 # This defines the latent change score factor as measured perfectly by scores on concept_t2concept_t2 ~ 0*1 # This line constrains the intercept of concept_t2 to 0concept_t2 ~~ 0*concept_t2 # This fixes the variance of concept_t2 to 0d_concept_1 ~ c("d_int_a", "d_int_b")*1 # This estimates the intercept of the change score concept_t1 ~ c("wb_int_a", "wb_int_b")*1 # This estimates the intercept of concept_t1 d_concept_1 ~~ c("d_var_a", "d_var_b")*d_concept_1 # This estimates the variance of the change scores concept_t1 ~~ c("wb_var_a", "wb_var_b")*concept_t1 # This estimates the variance of the concept_t1 d_concept_1 ~~ c("fb_a", "fb_b")*concept_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change scoreconcept_par1_t1 ~~ c("cov1a", "cov1b")*concept_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2concept_par2_t1 ~~ c("cov2a", "cov2b")*concept_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2concept_par3_t1 ~~ c("cov3a", "cov3b")*concept_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2concept_par1_t1 ~~ c("res1a", "res1b")*concept_par1_t1 # This allows residual variance on indicator X1 at T1 concept_par2_t1 ~~ c("res2a", "res2b")*concept_par2_t1 # This allows residual variance on indicator X2 at T1concept_par3_t1 ~~ c("res3a", "res3b")*concept_par3_t1 # This allows residual variance on indicator X3 at T1concept_par1_t2 ~~ c("res1a", "res1b")*concept_par1_t2 # This allows residual variance on indicator X1 at T2 concept_par2_t2 ~~ c("res2a", "res2b")*concept_par2_t2 # This allows residual variance on indicator X2 at T2 concept_par3_t2 ~~ c("res3a", "res3b")*concept_par3_t2 # This allows residual variance on indicator X3 at T2concept_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1concept_par2_t1 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T1concept_par3_t1 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T1concept_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2concept_par2_t2 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T2concept_par3_t2 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T2'lcs_concept_group_12_weak <-sem(mi_lcs_concept_group_weak, data=df_sbsa3_wide_wb %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal ="loadings")# strong invariancemi_lcs_concept_group_strong <-'concept_t1 =~ 1*concept_par1_t1 + c("lamb2", "lamb2")*concept_par2_t1 + c("lamb3", "lamb3")*concept_par3_t1 # This specifies the measurement model for concept_t1 concept_t2 =~ 1*concept_par1_t2 + c("lamb2", "lamb2")*concept_par2_t2 + c("lamb3", "lamb3")*concept_par3_t2 # This specifies the measurement model for concept_t2 with the equality constrained factor loadingsconcept_t2 ~ 1*concept_t1 # This parameter regresses concept_t2 perfectly on concept_t1d_concept_1 =~ 1*concept_t2 # This defines the latent change score factor as measured perfectly by scores on concept_t2concept_t2 ~ 0*1 # This line constrains the intercept of concept_t2 to 0concept_t2 ~~ 0*concept_t2 # This fixes the variance of concept_t2 to 0d_concept_1 ~ c("d_int", "d_int")*1 # This estimates the intercept of the change score concept_t1 ~ c("wb_int", "wb_int")*1 # This estimates the intercept of concept_t1 d_concept_1 ~~ c("d_var_a", "d_var_b")*d_concept_1 # This estimates the variance of the change scores concept_t1 ~~ c("wb_var_a", "wb_var_b")*concept_t1 # This estimates the variance of the concept_t1 d_concept_1 ~~ c("fb_a", "fb_b")*concept_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change scoreconcept_par1_t1 ~~ c("cov1a", "cov1b")*concept_par1_t2 # This allows residual covariance on indicator X1 across T1 and T2concept_par2_t1 ~~ c("cov2a", "cov2b")*concept_par2_t2 # This allows residual covariance on indicator X2 across T1 and T2concept_par3_t1 ~~ c("cov3a", "cov3b")*concept_par3_t2 # This allows residual covariance on indicator X3 across T1 and T2concept_par1_t1 ~~ c("res1a", "res1b")*concept_par1_t1 # This allows residual variance on indicator X1 at T1 concept_par2_t1 ~~ c("res2a", "res2b")*concept_par2_t1 # This allows residual variance on indicator X2 at T1concept_par3_t1 ~~ c("res3a", "res3b")*concept_par3_t1 # This allows residual variance on indicator X3 at T1concept_par1_t2 ~~ c("res1a", "res1b")*concept_par1_t2 # This allows residual variance on indicator X1 at T2 concept_par2_t2 ~~ c("res2a", "res2b")*concept_par2_t2 # This allows residual variance on indicator X2 at T2 concept_par3_t2 ~~ c("res3a", "res3b")*concept_par3_t2 # This allows residual variance on indicator X3 at T2concept_par1_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1concept_par2_t1 ~ c("m2", "m2")*1 # This estimates the intercept of X2 at T1concept_par3_t1 ~ c("m3", "m3")*1 # This estimates the intercept of X3 at T1concept_par1_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2concept_par2_t2 ~ c("m2", "m2")*1 # This estimates the intercept of X2 at T2concept_par3_t2 ~ c("m3", "m3")*1 # This estimates the intercept of X3 at T2'lcs_concept_group_12_strong <-sem(mi_lcs_concept_group_strong, data=df_sbsa3_wide_wb %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal =c("intercepts", "loadings"))
Self-concept clarity: results
# model comparison tests for measurement invariancelavTestLRT(lcs_concept_group_12_config, lcs_concept_group_12_weak, lcs_concept_group_12_strong)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
lcs_concept_group_12_config 24 3904.5 4020.6 30.375
lcs_concept_group_12_weak 26 3908.1 4016.4 37.911 7.7286 2
lcs_concept_group_12_strong 30 3905.3 3998.2 43.199 5.2123 4
Pr(>Chisq)
lcs_concept_group_12_config
lcs_concept_group_12_weak 0.02098 *
lcs_concept_group_12_strong 0.26620
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# show model with varying latent change parameters # -> key parameter is "d_concept_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 1, b = Group 2)params_lcs_concept_group_12_weak <- broom::tidy(lcs_concept_group_12_weak, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_concept_1 ~1 ")) %>%mutate(sig_diff =" ")kable(params_lcs_concept_group_12_weak, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_concept_1 ~1
d_int_a
0.159
0.324
3.578
0.000
d_concept_1 ~1
d_int_b
0.080
0.181
1.903
0.057
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(lcs_concept_group_12_strong, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_concept_1 ~1 ")), digits =3)
term
label
estimate
std.all
statistic
p.value
d_concept_1 ~1
d_int
0.117
0.237
3.826
0
d_concept_1 ~1
d_int
0.117
0.265
3.826
0
More positive change in self-concept clarity in the Group 1 compared to Group 2 but no substantial differences according to the LRTs. Slight caveat: weak measurement invariance could not be established as a first step at p < .05.
# whole model (weak invariance)summary(lcs_concept_group_12_weak, fit.measures=TRUE, standardized=TRUE, rsquare=F)
7.1.2 Latent change: differences in personality change
7.1.2.1 Run models
Adapt latent change score model from above (but without any moderation) and add grouping factor in estimation (adding vectorized equality constraints to the model step by step):
Show the code
# create templates:# configural invariancetrait_template_main_config <-'trait_t1 =~ 1*ind01_t1 + c("lamb2a", "lamb2b")*ind02_t1 + c("lamb3a", "lamb3b")*ind03_t1 # This specifies the measurement model for trait_t1 trait_t2 =~ 1*ind01_t2 + c("lamb2a", "lamb2b")*ind02_t2 + c("lamb3a", "lamb3b")*ind03_t2 # This specifies the measurement model for trait_t2 with the equality constrained factor loadingstrait_t2 ~ 1*trait_t1 # This parameter regresses trait_t2 perfectly on trait_t1d_trait_1 =~ 1*trait_t2 # This defines the latent change score factor as measured perfectly by scores on trait_t2trait_t2 ~ 0*1 # This line constrains the intercept of trait_t2 to 0trait_t2 ~~ 0*trait_t2 # This fixes the variance of trait_t2 to 0d_trait_1 ~ c("d_int_a", "d_int_b")*1 # This estimates the intercept of the change score trait_t1 ~ c("b5_int_a", "b5_int_b")*1 # This estimates the intercept of trait_t1 d_trait_1 ~~ c("d_var_a", "d_var_b")*d_trait_1 # This estimates the variance of the change scores trait_t1 ~~ c("b5_var_a", "b5_var_b")*trait_t1 # This estimates the variance of trait_t1 d_trait_1 ~~ c("fb_a", "fb_b")* trait_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change scoreind01_t1 ~~ c("cov1a", "cov1b")*ind01_t2 # This allows residual covariance on indicator X1 across T1 and T2ind02_t1 ~~ c("cov2a", "cov2b")*ind02_t2 # This allows residual covariance on indicator X2 across T1 and T2ind03_t1 ~~ c("cov3a", "cov3b")*ind03_t2 # This allows residual covariance on indicator X3 across T1 and T2ind01_t1 ~~ c("res1a", "res1b")*ind01_t1 # This allows residual variance on indicator X1 at T1 ind02_t1 ~~ c("res2a", "res2b")*ind02_t1 # This allows residual variance on indicator X2 at T1ind03_t1 ~~ c("res3a", "res3b")*ind03_t1 # This allows residual variance on indicator X3 at T1ind01_t2 ~~ c("res1a", "res1b")*ind01_t2 # This allows residual variance on indicator X1 at T2 ind02_t2 ~~ c("res2a", "res2b")*ind02_t2 # This allows residual variance on indicator X2 at T2 ind03_t2 ~~ c("res3a", "res3b")*ind03_t2 # This allows residual variance on indicator X3 at T2ind01_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1ind02_t1 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T1ind03_t1 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T1ind01_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2ind02_t2 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T2ind03_t2 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T2'# weak invariancetrait_template_main_weak <-'trait_t1 =~ 1*ind01_t1 + c("lamb2", "lamb2")*ind02_t1 + c("lamb3", "lamb3")*ind03_t1 # This specifies the measurement model for trait_t1 trait_t2 =~ 1*ind01_t2 + c("lamb2", "lamb2")*ind02_t2 + c("lamb3", "lamb3")*ind03_t2 # This specifies the measurement model for trait_t2 with the equality constrained factor loadingstrait_t2 ~ 1*trait_t1 # This parameter regresses trait_t2 perfectly on trait_t1d_trait_1 =~ 1*trait_t2 # This defines the latent change score factor as measured perfectly by scores on trait_t2trait_t2 ~ 0*1 # This line constrains the intercept of trait_t2 to 0trait_t2 ~~ 0*trait_t2 # This fixes the variance of trait_t2 to 0d_trait_1 ~ c("d_int_a", "d_int_b")*1 # This estimates the intercept of the change score trait_t1 ~ c("b5_int_a", "b5_int_b")*1 # This estimates the intercept of trait_t1 d_trait_1 ~~ c("d_var_a", "d_var_b")*d_trait_1 # This estimates the variance of the change scores trait_t1 ~~ c("b5_var_a", "b5_var_b")*trait_t1 # This estimates the variance of trait_t1 d_trait_1 ~~ c("fb_a", "fb_b")* trait_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change scoreind01_t1 ~~ c("cov1a", "cov1b")*ind01_t2 # This allows residual covariance on indicator X1 across T1 and T2ind02_t1 ~~ c("cov2a", "cov2b")*ind02_t2 # This allows residual covariance on indicator X2 across T1 and T2ind03_t1 ~~ c("cov3a", "cov3b")*ind03_t2 # This allows residual covariance on indicator X3 across T1 and T2ind01_t1 ~~ c("res1a", "res1b")*ind01_t1 # This allows residual variance on indicator X1 at T1 ind02_t1 ~~ c("res2a", "res2b")*ind02_t1 # This allows residual variance on indicator X2 at T1ind03_t1 ~~ c("res3a", "res3b")*ind03_t1 # This allows residual variance on indicator X3 at T1ind01_t2 ~~ c("res1a", "res1b")*ind01_t2 # This allows residual variance on indicator X1 at T2 ind02_t2 ~~ c("res2a", "res2b")*ind02_t2 # This allows residual variance on indicator X2 at T2 ind03_t2 ~~ c("res3a", "res3b")*ind03_t2 # This allows residual variance on indicator X3 at T2ind01_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1ind02_t1 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T1ind03_t1 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T1ind01_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2ind02_t2 ~ c("m2a", "m2b")*1 # This estimates the intercept of X2 at T2ind03_t2 ~ c("m3a", "m3b")*1 # This estimates the intercept of X3 at T2'# strong invariancetrait_template_main_strong <-'trait_t1 =~ 1*ind01_t1 + c("lamb2", "lamb2")*ind02_t1 + c("lamb3", "lamb3")*ind03_t1 # This specifies the measurement model for trait_t1 trait_t2 =~ 1*ind01_t2 + c("lamb2", "lamb2")*ind02_t2 + c("lamb3", "lamb3")*ind03_t2 # This specifies the measurement model for trait_t2 with the equality constrained factor loadingstrait_t2 ~ 1*trait_t1 # This parameter regresses trait_t2 perfectly on trait_t1d_trait_1 =~ 1*trait_t2 # This defines the latent change score factor as measured perfectly by scores on trait_t2trait_t2 ~ 0*1 # This line constrains the intercept of trait_t2 to 0trait_t2 ~~ 0*trait_t2 # This fixes the variance of trait_t2 to 0d_trait_1 ~ c("d_int", "d_int")*1 # This estimates the intercept of the change score trait_t1 ~ c("b5_int", "b5_int")*1 # This estimates the intercept of trait_t1 d_trait_1 ~~ c("d_var_a", "d_var_b")*d_trait_1 # This estimates the variance of the change scores trait_t1 ~~ c("b5_var_a", "b5_var_b")*trait_t1 # This estimates the variance of trait_t1 d_trait_1 ~~ c("fb_a", "fb_b")* trait_t1 # This estimates the self-feedback parameter, as a covariance! -> therefore, the interpretation of the change scoreind01_t1 ~~ c("cov1a", "cov1b")*ind01_t2 # This allows residual covariance on indicator X1 across T1 and T2ind02_t1 ~~ c("cov2a", "cov2b")*ind02_t2 # This allows residual covariance on indicator X2 across T1 and T2ind03_t1 ~~ c("cov3a", "cov3b")*ind03_t2 # This allows residual covariance on indicator X3 across T1 and T2ind01_t1 ~~ c("res1a", "res1b")*ind01_t1 # This allows residual variance on indicator X1 at T1 ind02_t1 ~~ c("res2a", "res2b")*ind02_t1 # This allows residual variance on indicator X2 at T1ind03_t1 ~~ c("res3a", "res3b")*ind03_t1 # This allows residual variance on indicator X3 at T1ind01_t2 ~~ c("res1a", "res1b")*ind01_t2 # This allows residual variance on indicator X1 at T2 ind02_t2 ~~ c("res2a", "res2b")*ind02_t2 # This allows residual variance on indicator X2 at T2 ind03_t2 ~~ c("res3a", "res3b")*ind03_t2 # This allows residual variance on indicator X3 at T2ind01_t1 ~ 0*1 # This constrains the intercept of X1 to 0 at T1ind02_t1 ~ c("m2", "m2")*1 # This estimates the intercept of X2 at T1ind03_t1 ~ c("m3", "m3")*1 # This estimates the intercept of X3 at T1ind01_t2 ~ 0*1 # This constrains the intercept of X1 to 0 at T2ind02_t2 ~ c("m2", "m2")*1 # This estimates the intercept of X2 at T2ind03_t2 ~ c("m3", "m3")*1 # This estimates the intercept of X3 at T2'# strict invariance -> not really needed for this analysis# loop across 5 traitsfor (i in1:5) { item_nrs = b5_vars[[i]][[1]] short_name =str_trunc(names(b5_vars)[i], 5, ellipsis ="")# configural - current template_filled_config_current <-str_replace_all(trait_template_main_config, c("trait"= short_name,"ind01"=paste0(short_name, "_curr_par1"), "ind02"=paste0(short_name, "_curr_par2"), "ind03"=paste0(short_name, "_curr_par3"))) trait_main_fit_config_current <-lavaan(template_filled_config_current, data = df_sbsa3_wide_pers %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group")eval(call("<-", as.name(paste0("lcs_", short_name, "_main_config_group_12")), template_filled_config_current))eval(call("<-", as.name(paste0("fit_lcs_", short_name, "_main_config_group_12")), trait_main_fit_config_current))# weak - current template_filled_weak_current <-str_replace_all(trait_template_main_weak, c("trait"= short_name,"ind01"=paste0(short_name, "_curr_par1"), "ind02"=paste0(short_name, "_curr_par2"), "ind03"=paste0(short_name, "_curr_par3"))) trait_main_fit_weak_current <-lavaan(template_filled_weak_current, data = df_sbsa3_wide_pers %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal ="loadings")eval(call("<-", as.name(paste0("lcs_", short_name, "_main_weak_group_12")), template_filled_weak_current))eval(call("<-", as.name(paste0("fit_lcs_", short_name, "_main_weak_group_12")), trait_main_fit_weak_current))# strong - current template_filled_strong_current <-str_replace_all(trait_template_main_strong, c("trait"= short_name,"ind01"=paste0(short_name, "_curr_par1"), "ind02"=paste0(short_name, "_curr_par2"), "ind03"=paste0(short_name, "_curr_par3"))) trait_main_fit_strong_current <-lavaan(template_filled_strong_current, data = df_sbsa3_wide_pers %>%filter(group!="Group 3"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal =c("intercepts", "loadings"))eval(call("<-", as.name(paste0("lcs_", short_name, "_main_strong_group_12")), template_filled_strong_current))eval(call("<-", as.name(paste0("fit_lcs_", short_name, "_main_strong_group_12")), trait_main_fit_strong_current))}
7.1.2.2 Current personality personality traits
Extraversion (current personality): results
# model comparison tests for measurement invariancelavTestLRT(fit_lcs_extra_main_config_group_12, fit_lcs_extra_main_weak_group_12, fit_lcs_extra_main_strong_group_12)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
fit_lcs_extra_main_config_group_12 24 3307.9 3423.9 24.541
fit_lcs_extra_main_weak_group_12 26 3307.4 3415.7 28.071 3.7366 2
fit_lcs_extra_main_strong_group_12 30 3302.9 3395.7 31.554 3.4568 4
Pr(>Chisq)
fit_lcs_extra_main_config_group_12
fit_lcs_extra_main_weak_group_12 0.1544
fit_lcs_extra_main_strong_group_12 0.4845
# show model with varying latent change parameters # -> key parameter is "d_extra_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 1, b = Group 2)params_main_lcs_extra_group_12 <- broom::tidy(fit_lcs_extra_main_weak_group_12, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_extra_1 ~1 ")) %>%mutate(sig_diff =" ")kable(params_main_lcs_extra_group_12, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_extra_1 ~1
d_int_a
0.074
0.37
2.775
0.006
d_extra_1 ~1
d_int_b
0.088
0.29
2.739
0.006
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(fit_lcs_extra_main_strong_group_12, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_extra_1 ~1 ")), digits =3)
Very similar change in extraversion in both groups. No significant differences according to the LRTs.
Agreeableness (current personality): results
# model comparison tests for measurement invariancelavTestLRT(fit_lcs_agree_main_config_group_12, fit_lcs_agree_main_weak_group_12, fit_lcs_agree_main_strong_group_12)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
fit_lcs_agree_main_config_group_12 24 3161.8 3277.9 39.952
fit_lcs_agree_main_weak_group_12 26 3158.5 3266.8 40.567 0.5738 2
fit_lcs_agree_main_strong_group_12 30 3156.4 3249.2 46.473 6.0557 4
Pr(>Chisq)
fit_lcs_agree_main_config_group_12
fit_lcs_agree_main_weak_group_12 0.7506
fit_lcs_agree_main_strong_group_12 0.1950
# show model with varying latent change parameters # -> key parameter is "d_agree_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 1, b = Group 2)params_main_lcs_agree_group_12 <- broom::tidy(fit_lcs_agree_main_weak_group_12, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_agree_1 ~1 ")) %>%mutate(sig_diff =" ")kable(params_main_lcs_agree_group_12, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_agree_1 ~1
d_int_a
0.051
0.176
1.727
0.084
d_agree_1 ~1
d_int_b
0.047
0.168
1.623
0.105
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(fit_lcs_agree_main_strong_group_12, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_agree_1 ~1 ")), digits =3)
Similar change in agreeableness in both groups. No significant differences according to the LRTs.
Conscientiousness (current personality): results
# model comparison tests for measurement invariancelavTestLRT(fit_lcs_consc_main_config_group_12, fit_lcs_consc_main_weak_group_12, fit_lcs_consc_main_strong_group_12)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
fit_lcs_consc_main_config_group_12 24 3310.7 3426.8 27.774
fit_lcs_consc_main_weak_group_12 26 3307.5 3415.8 28.559 0.9105 2
fit_lcs_consc_main_strong_group_12 30 3302.7 3395.6 31.826 3.2967 4
Pr(>Chisq)
fit_lcs_consc_main_config_group_12
fit_lcs_consc_main_weak_group_12 0.6343
fit_lcs_consc_main_strong_group_12 0.5094
# show model with varying latent change parameters # -> key parameter is "d_consc_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 1, b = Group 2)params_main_lcs_consc_group_12 <- broom::tidy(fit_lcs_consc_main_weak_group_12, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_consc_1 ~1 ")) %>%mutate(sig_diff =" ")kable(params_main_lcs_consc_group_12, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_consc_1 ~1
d_int_a
0.099
0.326
2.925
0.003
d_consc_1 ~1
d_int_b
0.068
0.276
2.365
0.018
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(fit_lcs_consc_main_strong_group_12, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_consc_1 ~1 ")), digits =3)
Similar change in conscientiousness in both groups (increase is slightly larger in Group 1 compared to Group 2). No significant differences according to the LRTs.
Neuroticism (current personality): results
# model comparison tests for measurement invariancelavTestLRT(fit_lcs_neuro_main_config_group_12, fit_lcs_neuro_main_weak_group_12, fit_lcs_neuro_main_strong_group_12)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
fit_lcs_neuro_main_config_group_12 24 3307.8 3423.9 33.029
fit_lcs_neuro_main_weak_group_12 26 3303.9 3412.2 33.086 0.0598 2
fit_lcs_neuro_main_strong_group_12 30 3299.2 3392.1 36.416 3.3577 4
Pr(>Chisq)
fit_lcs_neuro_main_config_group_12
fit_lcs_neuro_main_weak_group_12 0.9705
fit_lcs_neuro_main_strong_group_12 0.4998
# show model with varying latent change parameters # -> key parameter is "d_neuro_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 1, b = Group 2)params_main_lcs_neuro_group_12 <- broom::tidy(fit_lcs_neuro_main_weak_group_12, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_neuro_1 ~1 ")) %>%mutate(sig_diff =" ")kable(params_main_lcs_neuro_group_12, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_neuro_1 ~1
d_int_a
-0.052
-0.145
-1.436
0.151
d_neuro_1 ~1
d_int_b
-0.128
-0.462
-4.271
0.000
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(fit_lcs_neuro_main_strong_group_12, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_neuro_1 ~1 ")), digits =3)
Small decreases in neuroticism in both groups. Decrease is larger in Group 2 compared to Group 1. No significant differences according to the LRTs.
Openness (current personality): results
# model comparison tests for measurement invariancelavTestLRT(fit_lcs_openn_main_config_group_12, fit_lcs_openn_main_weak_group_12, fit_lcs_openn_main_strong_group_12)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
fit_lcs_openn_main_config_group_12 24 3369.4 3485.5 30.630
fit_lcs_openn_main_weak_group_12 26 3365.5 3473.9 30.784 0.14398 2
fit_lcs_openn_main_strong_group_12 30 3359.3 3452.1 32.526 1.71588 4
Pr(>Chisq)
fit_lcs_openn_main_config_group_12
fit_lcs_openn_main_weak_group_12 0.9305
fit_lcs_openn_main_strong_group_12 0.7878
# show model with varying latent change parameters # -> key parameter is "d_openn_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 1, b = Group 2)params_main_lcs_openn_group_12 <- broom::tidy(fit_lcs_openn_main_weak_group_12, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_openn_1 ~1 ")) %>%mutate(sig_diff =" ")kable(params_main_lcs_openn_group_12, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_openn_1 ~1
d_int_a
0.022
0.110
0.821
0.412
d_openn_1 ~1
d_int_b
0.044
0.221
1.798
0.072
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(fit_lcs_openn_main_strong_group_12, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_openn_1 ~1 ")), digits =3)
Almost no change in current personality openness in both groups. No significant differences according to the LRTs.
7.1.2.3 Ideal personality traits
In Study 3, we can only examine this in Group 1, so no multi-group comparison of ideal personality possible.
7.2 Group 2 vs. Group 3: Effect of demand characteristics
7.2.1 Well-being change: differences across groups
7.2.1.1 Life satisfaction
Life satisfaction: fitting multi-group models
Show the code
# adapt latent change score model from above and add grouping factor in estimation (also add vectorized equality constraints to the model)# configural invariance -> model template created abovelcs_swls_group_23_config <-sem(mi_lcs_swls_group_config, data=df_sbsa3_wide_wb %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group")# weak invariance -> model template created abovelcs_swls_group_23_weak <-sem(mi_lcs_swls_group_weak, data=df_sbsa3_wide_wb %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal ="loadings")# strong invariance -> model template created abovelcs_swls_group_23_strong <-sem(mi_lcs_swls_group_strong, data=df_sbsa3_wide_wb %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal =c("intercepts", "loadings"))
Life satisfaction: results
# model comparison tests for measurement invariancelavTestLRT(lcs_swls_group_23_config, lcs_swls_group_23_weak, lcs_swls_group_23_strong)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff Pr(>Chisq)
lcs_swls_group_23_config 50 6785.3 6932.4 85.341
lcs_swls_group_23_weak 53 6779.9 6915.4 85.974 0.6112 3 0.89386
lcs_swls_group_23_strong 58 6785.8 6902.0 101.870 15.7264 5 0.00767
lcs_swls_group_23_config
lcs_swls_group_23_weak
lcs_swls_group_23_strong **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# show model with varying latent change parameters # -> key parameter is "d_swls_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 2, b = Group 3)params_lcs_swls_group_23_weak <- broom::tidy(lcs_swls_group_23_weak, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_swls_1 ~1 ")) %>%mutate(sig_diff ="**")kable(params_lcs_swls_group_23_weak, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_swls_1 ~1
d_int_a
0.255
0.511
4.850
0.00
**
d_swls_1 ~1
d_int_b
0.019
0.034
0.358
0.72
**
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(lcs_swls_group_23_strong, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_swls_1 ~1 ")), digits =3)
term
label
estimate
std.all
statistic
p.value
d_swls_1 ~1
d_int
0.14
0.275
3.377
0.001
d_swls_1 ~1
d_int
0.14
0.241
3.377
0.001
Significantly more positive change in life satisfaction in the Group 2 compared to Group 3 (difference significant according to the LRT). Change almost zero in Group 3.
# whole model (weak invariance)summary(lcs_swls_group_23_weak, fit.measures=TRUE, standardized=TRUE, rsquare=F)
# adapt latent change score model from above and add grouping factor in estimation (also add vectorized equality constraints to the model)# configural invariance -> model template created abovelcs_meaning_group_23_config <-sem(mi_lcs_meaning_group_config, data=df_sbsa3_wide_wb %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group")# weak invariance -> model template created abovelcs_meaning_group_23_weak <-sem(mi_lcs_meaning_group_weak, data=df_sbsa3_wide_wb %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal ="loadings")# strong invariance -> model template created abovelcs_meaning_group_23_strong <-sem(mi_lcs_meaning_group_strong, data=df_sbsa3_wide_wb %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal =c("intercepts", "loadings"))
Meaning in life: results
# model comparison tests for measurement invariancelavTestLRT(lcs_meaning_group_23_config, lcs_meaning_group_23_weak, lcs_meaning_group_23_strong)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
lcs_meaning_group_23_config 24 5066.7 5182.9 34.651
lcs_meaning_group_23_weak 26 5063.3 5171.7 35.210 0.6420 2
lcs_meaning_group_23_strong 30 5059.6 5152.6 39.545 4.2488 4
Pr(>Chisq)
lcs_meaning_group_23_config
lcs_meaning_group_23_weak 0.7254
lcs_meaning_group_23_strong 0.3734
# show model with varying latent change parameters # -> key parameter is "d_meaning_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 2, b = Group 3)params_lcs_meaning_group_23_weak <- broom::tidy(lcs_meaning_group_23_weak, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_meaning_1 ~1 ")) %>%mutate(sig_diff =" ")kable(params_lcs_meaning_group_23_weak, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_meaning_1 ~1
d_int_a
0.114
0.196
1.994
0.046
d_meaning_1 ~1
d_int_b
0.084
0.146
1.578
0.115
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(lcs_meaning_group_23_strong, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_meaning_1 ~1 ")), digits =3)
term
label
estimate
std.all
statistic
p.value
d_meaning_1 ~1
d_int
0.097
0.165
2.449
0.014
d_meaning_1 ~1
d_int
0.097
0.168
2.449
0.014
Slightly more positive change in meaning in life in the Group 2 compared to Group 3 but no substantial differences according to the LRTs and not significantly different from zero in all models at p < .01.
# whole model (weak invariance)summary(lcs_meaning_group_23_weak, fit.measures=TRUE, standardized=TRUE, rsquare=F)
# adapt latent change score model from above and add grouping factor in estimation (also add vectorized equality constraints to the model)# configural invariance -> model template created abovelcs_selfes_group_23_config <-sem(mi_lcs_selfes_group_config, data=df_sbsa3_wide_wb %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group")# weak invariance -> model template created abovelcs_selfes_group_23_weak <-sem(mi_lcs_selfes_group_weak, data=df_sbsa3_wide_wb %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal ="loadings")# strong invariance -> model template created abovelcs_selfes_group_23_strong <-sem(mi_lcs_selfes_group_strong, data=df_sbsa3_wide_wb %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal =c("intercepts", "loadings"))
Self-esteem: results
# model comparison tests for measurement invariancelavTestLRT(lcs_selfes_group_23_config, lcs_selfes_group_23_weak, lcs_selfes_group_23_strong)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
lcs_selfes_group_23_config 24 3712.6 3828.7 23.270
lcs_selfes_group_23_weak 26 3711.2 3819.6 25.907 2.5162 2
lcs_selfes_group_23_strong 30 3719.4 3812.3 42.088 15.7913 4
Pr(>Chisq)
lcs_selfes_group_23_config
lcs_selfes_group_23_weak 0.284188
lcs_selfes_group_23_strong 0.003312 **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# show model with varying latent change parameters # -> key parameter is "d_selfes_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 2, b = Group 3)params_lcs_selfes_group_23_weak <- broom::tidy(lcs_selfes_group_23_weak, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_selfes_1 ~1 ")) %>%mutate(sig_diff ="**")kable(params_lcs_selfes_group_23_weak, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_selfes_1 ~1
d_int_a
0.164
0.399
4.161
0.000
**
d_selfes_1 ~1
d_int_b
0.009
0.028
0.283
0.777
**
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(lcs_selfes_group_23_strong, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_selfes_1 ~1 ")), digits =3)
term
label
estimate
std.all
statistic
p.value
d_selfes_1 ~1
d_int
0.07
0.166
2.517
0.012
d_selfes_1 ~1
d_int
0.07
0.204
2.517
0.012
Significant positive change in self-esteem in the Group 2 but no change in Grouo 3. Significant difference according to the LRT.
# whole model (weak invariance)summary(lcs_selfes_group_23_weak, fit.measures=TRUE, standardized=TRUE, rsquare=F)
# adapt latent change score model from above and add grouping factor in estimation (also add vectorized equality constraints to the model)# configural invariance -> model template created abovelcs_concept_group_23_config <-sem(mi_lcs_concept_group_config, data=df_sbsa3_wide_wb %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group")# weak invariance -> model template created abovelcs_concept_group_23_weak <-sem(mi_lcs_concept_group_weak, data=df_sbsa3_wide_wb %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal ="loadings")# strong invariance -> model template created abovelcs_concept_group_23_strong <-sem(mi_lcs_concept_group_strong, data=df_sbsa3_wide_wb %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml',group ="group", group.equal =c("intercepts", "loadings"))
Self-concept clarity: results
# model comparison tests for measurement invariancelavTestLRT(lcs_concept_group_23_config, lcs_concept_group_23_weak, lcs_concept_group_23_strong)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
lcs_concept_group_23_config 24 3897.8 4014.0 27.042
lcs_concept_group_23_weak 26 3896.1 4004.5 29.306 2.2311 2
lcs_concept_group_23_strong 30 3896.8 3989.7 38.030 8.5761 4
Pr(>Chisq)
lcs_concept_group_23_config
lcs_concept_group_23_weak 0.32773
lcs_concept_group_23_strong 0.07261 .
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# show model with varying latent change parameters # -> key parameter is "d_concept_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 2, b = Group 3)params_lcs_concept_group_23_weak <- broom::tidy(lcs_concept_group_23_weak, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_concept_1 ~1 ")) %>%mutate(sig_diff =" ")kable(params_lcs_concept_group_23_weak, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_concept_1 ~1
d_int_a
0.076
0.179
1.888
0.059
d_concept_1 ~1
d_int_b
0.076
0.198
2.127
0.033
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(lcs_concept_group_23_strong, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_concept_1 ~1 ")), digits =3)
term
label
estimate
std.all
statistic
p.value
d_concept_1 ~1
d_int
0.077
0.181
2.855
0.004
d_concept_1 ~1
d_int
0.077
0.201
2.855
0.004
Only very small positive change in self-concept clarity both groups (very similar in the two groups), that is n.s. in the weak invariance model but significant in the strong invariance model. No substantial differences according to the LRTs.
# whole model (weak invariance)summary(lcs_concept_group_23_weak, fit.measures=TRUE, standardized=TRUE, rsquare=F)
7.2.2 Latent change: differences in personality change
7.2.2.1 Run models
Adapt latent change score model from above (but without any moderation) and add grouping factor in estimation (adding vectorized equality constraints to the model step by step):
Show the code
# create templates: (same as those already created above)# loop across 5 traitsfor (i in1:5) { item_nrs = b5_vars[[i]][[1]] short_name =str_trunc(names(b5_vars)[i], 5, ellipsis ="")# configural - current template_filled_config_current <-str_replace_all(trait_template_main_config, c("trait"= short_name,"ind01"=paste0(short_name, "_curr_par1"), "ind02"=paste0(short_name, "_curr_par2"), "ind03"=paste0(short_name, "_curr_par3"))) trait_main_fit_config_current <-lavaan(template_filled_config_current, data = df_sbsa3_wide_pers %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group")eval(call("<-", as.name(paste0("lcs_", short_name, "_main_config_group_23")), template_filled_config_current))eval(call("<-", as.name(paste0("fit_lcs_", short_name, "_main_config_group_23")), trait_main_fit_config_current))# weak - current template_filled_weak_current <-str_replace_all(trait_template_main_weak, c("trait"= short_name,"ind01"=paste0(short_name, "_curr_par1"), "ind02"=paste0(short_name, "_curr_par2"), "ind03"=paste0(short_name, "_curr_par3"))) trait_main_fit_weak_current <-lavaan(template_filled_weak_current, data = df_sbsa3_wide_pers %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal ="loadings")eval(call("<-", as.name(paste0("lcs_", short_name, "_main_weak_group_23")), template_filled_weak_current))eval(call("<-", as.name(paste0("fit_lcs_", short_name, "_main_weak_group_23")), trait_main_fit_weak_current))# strong - current template_filled_strong_current <-str_replace_all(trait_template_main_strong, c("trait"= short_name,"ind01"=paste0(short_name, "_curr_par1"), "ind02"=paste0(short_name, "_curr_par2"), "ind03"=paste0(short_name, "_curr_par3"))) trait_main_fit_strong_current <-lavaan(template_filled_strong_current, data = df_sbsa3_wide_pers %>%filter(group!="Group 1"), estimator='mlr', fixed.x=FALSE, missing='fiml', group ="group", group.equal =c("intercepts", "loadings"))eval(call("<-", as.name(paste0("lcs_", short_name, "_main_strong_group_23")), template_filled_strong_current))eval(call("<-", as.name(paste0("fit_lcs_", short_name, "_main_strong_group_23")), trait_main_fit_strong_current))}
7.2.2.2 Current personality personality traits
Extraversion (current personality): results
# model comparison tests for measurement invariancelavTestLRT(fit_lcs_extra_main_config_group_23, fit_lcs_extra_main_weak_group_23, fit_lcs_extra_main_strong_group_23)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
fit_lcs_extra_main_config_group_23 24 3313.7 3429.9 35.195
fit_lcs_extra_main_weak_group_23 26 3312.4 3420.9 37.936 2.9066 2
fit_lcs_extra_main_strong_group_23 30 3317.8 3410.7 51.292 12.9389 4
Pr(>Chisq)
fit_lcs_extra_main_config_group_23
fit_lcs_extra_main_weak_group_23 0.23380
fit_lcs_extra_main_strong_group_23 0.01158 *
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# show model with varying latent change parameters # -> key parameter is "d_extra_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 2, b = Group 3)params_main_lcs_extra_group_23 <- broom::tidy(fit_lcs_extra_main_weak_group_23, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_extra_1 ~1 ")) %>%mutate(sig_diff ="*")kable(params_main_lcs_extra_group_23, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_extra_1 ~1
d_int_a
0.091
0.284
2.694
0.007
*
d_extra_1 ~1
d_int_b
-0.039
-0.258
-1.530
0.126
*
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(fit_lcs_extra_main_strong_group_23, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_extra_1 ~1 ")), digits =3)
Small but significant change in extraversion in Group 2 but no significant change in Group 3 (in weak invariance model). No change in strong invariance model. According to the LRT, only weak invariance is given (at p < .05; strong at p < .01).
Agreeableness (current personality): results
# model comparison tests for measurement invariancelavTestLRT(fit_lcs_agree_main_config_group_23, fit_lcs_agree_main_weak_group_23, fit_lcs_agree_main_strong_group_23)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
fit_lcs_agree_main_config_group_23 24 3226.1 3342.2 33.599
fit_lcs_agree_main_weak_group_23 26 3224.0 3332.4 35.570 2.0013 2
fit_lcs_agree_main_strong_group_23 30 3219.1 3312.1 38.679 2.9883 4
Pr(>Chisq)
fit_lcs_agree_main_config_group_23
fit_lcs_agree_main_weak_group_23 0.3676
fit_lcs_agree_main_strong_group_23 0.5598
# show model with varying latent change parameters # -> key parameter is "d_agree_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 2, b = Group 3)params_main_lcs_agree_group_23 <- broom::tidy(fit_lcs_agree_main_weak_group_23, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_agree_1 ~1 ")) %>%mutate(sig_diff =" ")kable(params_main_lcs_agree_group_23, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_agree_1 ~1
d_int_a
0.044
0.170
1.603
0.109
d_agree_1 ~1
d_int_b
-0.007
-0.049
-0.324
0.746
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(fit_lcs_agree_main_strong_group_23, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_agree_1 ~1 ")), digits =3)
No change in agreeableness in both groups (increase is a tiny bit larger in Group 2 compared to Group 3). No significant differences according to the LRTs.
Conscientiousness (current personality): results
# model comparison tests for measurement invariancelavTestLRT(fit_lcs_consc_main_config_group_23, fit_lcs_consc_main_weak_group_23, fit_lcs_consc_main_strong_group_23)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
fit_lcs_consc_main_config_group_23 24 3093.7 3209.9 24.840
fit_lcs_consc_main_weak_group_23 26 3090.4 3198.8 25.499 0.7707 2
fit_lcs_consc_main_strong_group_23 30 3095.5 3188.4 38.635 12.7522 4
Pr(>Chisq)
fit_lcs_consc_main_config_group_23
fit_lcs_consc_main_weak_group_23 0.68022
fit_lcs_consc_main_strong_group_23 0.01255 *
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# show model with varying latent change parameters # -> key parameter is "d_consc_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 2, b = Group 3)params_main_lcs_consc_group_23 <- broom::tidy(fit_lcs_consc_main_weak_group_23, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_consc_1 ~1 ")) %>%mutate(sig_diff ="*")kable(params_main_lcs_consc_group_23, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_consc_1 ~1
d_int_a
0.068
0.278
2.389
0.017
*
d_consc_1 ~1
d_int_b
0.040
0.167
1.487
0.137
*
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(fit_lcs_consc_main_strong_group_23, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_consc_1 ~1 ")), digits =3)
Small positive change in conscientiousness in both groups. This increase is slightly larger in Group 2 compared to Group 3. No significant differences according to the LRTs (at p < .01, but strong invariance not given at p < .05).
Neuroticism (current personality): results
# model comparison tests for measurement invariancelavTestLRT(fit_lcs_neuro_main_config_group_23, fit_lcs_neuro_main_weak_group_23, fit_lcs_neuro_main_strong_group_23)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
fit_lcs_neuro_main_config_group_23 24 3165.7 3281.8 38.800
fit_lcs_neuro_main_weak_group_23 26 3162.0 3270.5 39.162 0.3657 2
fit_lcs_neuro_main_strong_group_23 30 3170.2 3263.1 55.319 16.8305 4
Pr(>Chisq)
fit_lcs_neuro_main_config_group_23
fit_lcs_neuro_main_weak_group_23 0.832882
fit_lcs_neuro_main_strong_group_23 0.002085 **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# show model with varying latent change parameters # -> key parameter is "d_neuro_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 2, b = Group 3)params_main_lcs_neuro_group_23 <- broom::tidy(fit_lcs_neuro_main_weak_group_23, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_neuro_1 ~1 ")) %>%mutate(sig_diff ="**")kable(params_main_lcs_neuro_group_23, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_neuro_1 ~1
d_int_a
-0.125
-0.459
-4.268
0.000
**
d_neuro_1 ~1
d_int_b
0.018
0.059
0.578
0.563
**
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(fit_lcs_neuro_main_strong_group_23, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_neuro_1 ~1 ")), digits =3)
Significant decrease in neuroticism only in Group 2, no change in Group 3. Significant difference according to the LRT (strong invariance not given!).
Openness (current personality): results
# model comparison tests for measurement invariancelavTestLRT(fit_lcs_openn_main_config_group_23, fit_lcs_openn_main_weak_group_23, fit_lcs_openn_main_strong_group_23)
Scaled Chi-Squared Difference Test (method = "satorra.bentler.2001")
lavaan NOTE:
The "Chisq" column contains standard test statistics, not the
robust test that should be reported per model. A robust difference
test is a function of two standard (not robust) statistics.
Df AIC BIC Chisq Chisq diff Df diff
fit_lcs_openn_main_config_group_23 24 3290.0 3406.1 22.233
fit_lcs_openn_main_weak_group_23 26 3287.8 3396.3 24.097 1.9657 2
fit_lcs_openn_main_strong_group_23 30 3284.3 3377.2 28.526 4.2923 4
Pr(>Chisq)
fit_lcs_openn_main_config_group_23
fit_lcs_openn_main_weak_group_23 0.3742
fit_lcs_openn_main_strong_group_23 0.3679
# show model with varying latent change parameters # -> key parameter is "d_openn_1 ~1"# labelled parameter as "d_int_a" & "d_int_b" (a = Group 2, b = Group 3)params_main_lcs_openn_group_23 <- broom::tidy(fit_lcs_openn_main_weak_group_23, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_openn_1 ~1 ")) %>%mutate(sig_diff =" ")kable(params_main_lcs_openn_group_23, digits =3)
term
label
estimate
std.all
statistic
p.value
sig_diff
d_openn_1 ~1
d_int_a
0.042
0.217
1.766
0.077
d_openn_1 ~1
d_int_b
-0.001
-0.013
-0.035
0.972
# constrained to be equal in the strong measurement invariance model:kable(broom::tidy(fit_lcs_openn_main_strong_group_23, conf.int =TRUE, conf.level =0.99) %>%select(term, label, estimate, std.all, statistic, p.value) %>%filter(term %in%c("d_openn_1 ~1 ")), digits =3)
Almost no change in current personality openness in both groups but slightly stronger increase in Group 2 compared to Group 3. No significant differences according to the LRTs, though.
kable(df_manip_check_curr_unlist_12 %>%mutate(outcome =rep(sort(names(b5_vars)), each=4), term =c(rep(c("Intercept", "time", "group_1", "time*group_1"), 20))) %>%rename(p =`Pr(>|t|)`, str_err =`Std. Error`, est = Estimate) %>%select(outcome, term, est, str_err, p) %>%mutate(sig =ifelse(p < .05, ifelse(p < .01, ifelse(p < .001, "***", "**"), "*"), " ")) %>%arrange(factor(outcome, levels = (names(b5_vars)))), # order by BFI traits, digits =3)
outcome
term
est
str_err
p
sig
extraversion
Intercept
2.921
0.056
0.000
***
extraversion
time
0.090
0.031
0.003
**
extraversion
group_1
-0.089
0.080
0.266
extraversion
time*group_1
-0.014
0.043
0.743
agreeableness
Intercept
3.615
0.043
0.000
***
agreeableness
time
0.052
0.034
0.125
agreeableness
group_1
0.072
0.061
0.237
agreeableness
time*group_1
-0.002
0.048
0.961
conscientiousness
Intercept
3.364
0.055
0.000
***
conscientiousness
time
0.063
0.032
0.048
*
conscientiousness
group_1
-0.034
0.078
0.657
conscientiousness
time*group_1
0.036
0.045
0.424
neuroticism
Intercept
3.263
0.063
0.000
***
neuroticism
time
-0.143
0.035
0.000
***
neuroticism
group_1
-0.074
0.090
0.412
neuroticism
time*group_1
0.087
0.049
0.078
openness
Intercept
3.704
0.048
0.000
***
openness
time
0.055
0.029
0.061
openness
group_1
0.027
0.068
0.687
openness
time*group_1
-0.028
0.041
0.497
sociability
Intercept
2.634
0.075
0.000
***
sociability
time
0.140
0.041
0.001
***
sociability
group_1
-0.179
0.106
0.093
sociability
time*group_1
-0.008
0.058
0.886
assertiveness
Intercept
2.966
0.067
0.000
***
assertiveness
time
0.025
0.045
0.584
assertiveness
group_1
-0.041
0.095
0.663
assertiveness
time*group_1
-0.008
0.064
0.903
energy
Intercept
3.162
0.064
0.000
***
energy
time
0.106
0.046
0.022
*
energy
group_1
-0.046
0.091
0.611
energy
time*group_1
-0.029
0.065
0.650
compassion
Intercept
3.779
0.053
0.000
***
compassion
time
-0.014
0.051
0.779
compassion
group_1
0.020
0.075
0.792
compassion
time*group_1
0.134
0.072
0.064
respectfulness
Intercept
3.955
0.051
0.000
***
respectfulness
time
0.062
0.043
0.145
respectfulness
group_1
0.099
0.072
0.171
respectfulness
time*group_1
-0.050
0.060
0.401
trust
Intercept
3.112
0.060
0.000
***
trust
time
0.114
0.048
0.020
*
trust
group_1
0.099
0.085
0.243
trust
time*group_1
-0.090
0.068
0.190
organization
Intercept
3.446
0.075
0.000
***
organization
time
0.045
0.047
0.340
organization
group_1
-0.043
0.107
0.689
organization
time*group_1
0.036
0.067
0.590
productiveness
Intercept
3.161
0.065
0.000
***
productiveness
time
0.103
0.048
0.033
*
productiveness
group_1
-0.132
0.093
0.156
productiveness
time*group_1
0.038
0.068
0.580
responsibility
Intercept
3.486
0.057
0.000
***
responsibility
time
0.049
0.044
0.265
responsibility
group_1
0.072
0.081
0.379
responsibility
time*group_1
0.025
0.062
0.693
anxiety
Intercept
3.602
0.069
0.000
***
anxiety
time
-0.090
0.046
0.049
*
anxiety
group_1
-0.069
0.098
0.484
anxiety
time*group_1
0.065
0.064
0.316
depression
Intercept
3.176
0.073
0.000
***
depression
time
-0.216
0.046
0.000
***
depression
group_1
-0.086
0.104
0.413
depression
time*group_1
0.141
0.065
0.032
*
volatility
Intercept
3.011
0.074
0.000
***
volatility
time
-0.127
0.053
0.017
*
volatility
group_1
-0.067
0.106
0.527
volatility
time*group_1
0.060
0.074
0.422
curiosity
Intercept
3.880
0.054
0.000
***
curiosity
time
0.075
0.040
0.059
curiosity
group_1
-0.008
0.077
0.914
curiosity
time*group_1
-0.030
0.056
0.597
aesthetic
Intercept
3.599
0.062
0.000
***
aesthetic
time
0.025
0.046
0.589
aesthetic
group_1
-0.008
0.089
0.930
aesthetic
time*group_1
-0.008
0.065
0.898
imagination
Intercept
3.633
0.060
0.000
***
imagination
time
0.069
0.046
0.137
imagination
group_1
0.100
0.086
0.246
imagination
time*group_1
-0.048
0.066
0.464
No significant group_1 effects (higher trait level in Group 1 at baseline) and also no significant differences in the changes over time in current personality trait levels (timeXgroup) at p < .01 (only for depression at p < .05). Significant changes over time in current personality trait levels (time) for extraversion (also sociability) and neuroticism (also depression.
Plot of main effects: extraversion and neuroticism
Show the code
ggeffects::ggpredict(df_manip_check_curr_12$extraversion, terms =c("time_d[0,1]", "group_1[0,1]")) |>plot() +aes(linetype=group, color=group, shape=group) +geom_point() +theme_light() +scale_x_continuous(breaks =c(0,1), labels =c("T1", "T2")) +theme(panel.grid.minor.x =element_blank()) +labs(title ="Extraversion", x ="Time", y ="Predicted values of\nextraversion",linetype="Group\n(0 = Group 2,\n1 = Group 1)", color="Group\n(0 = Group 2,\n1 = Group 1)", shape="Group\n(0 = Group 2,\n1 = Group 1)")
Show the code
ggeffects::ggpredict(df_manip_check_curr_12$neuroticism, terms =c("time_d[0,1]", "group_1[0,1]")) |>plot() +aes(linetype=group, color=group, shape=group) +geom_point() +theme_light() +scale_x_continuous(breaks =c(0,1), labels =c("T1", "T2")) +theme(panel.grid.minor.x =element_blank()) +labs(title ="Neuroticism", x ="Time", y ="Predicted values of\nneuroticism",linetype="Group\n(0 = Group 2,\n1 = Group 1)", color="Group\n(0 = Group 2,\n1 = Group 1)", shape="Group\n(0 = Group 2,\n1 = Group 1)")
Group interaction effect: Depression (but only at p < .05)
Show the code
ggeffects::ggpredict(df_manip_check_curr_12$depression, terms =c("time_d[0,1]", "group_1[0,1]")) |>plot() +aes(linetype=group, color=group, shape=group) +geom_point() +theme_light() +scale_x_continuous(breaks =c(0,1), labels =c("T1", "T2")) +theme(panel.grid.minor.x =element_blank()) +labs(title ="Depression", x ="Time", y ="Predicted values of\ndepression",linetype="Group\n(0 = Group 2,\n1 = Group 1)", color="Group\n(0 = Group 2,\n1 = Group 1)", shape="Group\n(0 = Group 2,\n1 = Group 1)")
kable(df_manip_check_curr_unlist_23 %>%mutate(outcome =rep(sort(names(b5_vars)), each=4), term =c(rep(c("Intercept", "time", "group_2", "time*group_2"), 20))) %>%rename(p =`Pr(>|t|)`, str_err =`Std. Error`, est = Estimate) %>%select(outcome, term, est, str_err, p) %>%mutate(sig =ifelse(p < .05, ifelse(p < .01, ifelse(p < .001, "***", "**"), "*"), " ")) %>%arrange(factor(outcome, levels = (names(b5_vars)))), # order by BFI traits, digits =3)
outcome
term
est
str_err
p
sig
extraversion
Intercept
3.069
0.058
0.000
***
extraversion
time
-0.036
0.029
0.207
extraversion
group_2
-0.148
0.081
0.070
extraversion
time*group_2
0.127
0.041
0.002
**
agreeableness
Intercept
3.689
0.046
0.000
***
agreeableness
time
-0.005
0.030
0.876
agreeableness
group_2
-0.073
0.065
0.256
agreeableness
time*group_2
0.056
0.043
0.201
conscientiousness
Intercept
3.543
0.056
0.000
***
conscientiousness
time
0.042
0.028
0.139
conscientiousness
group_2
-0.179
0.078
0.023
*
conscientiousness
time*group_2
0.021
0.040
0.605
neuroticism
Intercept
3.032
0.067
0.000
***
neuroticism
time
0.014
0.031
0.648
neuroticism
group_2
0.231
0.095
0.015
*
neuroticism
time*group_2
-0.157
0.045
0.001
***
openness
Intercept
3.834
0.049
0.000
***
openness
time
-0.008
0.024
0.749
openness
group_2
-0.130
0.070
0.063
openness
time*group_2
0.063
0.035
0.075
sociability
Intercept
2.696
0.078
0.000
***
sociability
time
0.014
0.039
0.720
sociability
group_2
-0.062
0.109
0.571
sociability
time*group_2
0.126
0.056
0.025
*
assertiveness
Intercept
3.173
0.068
0.000
***
assertiveness
time
-0.061
0.041
0.144
assertiveness
group_2
-0.207
0.096
0.032
*
assertiveness
time*group_2
0.086
0.059
0.148
energy
Intercept
3.337
0.067
0.000
***
energy
time
-0.062
0.045
0.167
energy
group_2
-0.175
0.095
0.065
energy
time*group_2
0.167
0.064
0.009
**
compassion
Intercept
3.807
0.057
0.000
***
compassion
time
-0.018
0.048
0.710
compassion
group_2
-0.027
0.081
0.733
compassion
time*group_2
0.001
0.068
0.989
respectfulness
Intercept
4.009
0.051
0.000
***
respectfulness
time
0.036
0.040
0.365
respectfulness
group_2
-0.053
0.072
0.461
respectfulness
time*group_2
0.026
0.057
0.652
trust
Intercept
3.251
0.062
0.000
***
trust
time
-0.032
0.042
0.457
trust
group_2
-0.140
0.088
0.112
trust
time*group_2
0.143
0.061
0.019
*
organization
Intercept
3.685
0.074
0.000
***
organization
time
-0.049
0.041
0.238
organization
group_2
-0.239
0.104
0.022
*
organization
time*group_2
0.093
0.059
0.114
productiveness
Intercept
3.345
0.066
0.000
***
productiveness
time
0.139
0.042
0.001
**
productiveness
group_2
-0.185
0.092
0.047
*
productiveness
time*group_2
-0.038
0.060
0.529
responsibility
Intercept
3.598
0.056
0.000
***
responsibility
time
0.033
0.041
0.421
responsibility
group_2
-0.112
0.079
0.157
responsibility
time*group_2
0.016
0.058
0.785
anxiety
Intercept
3.412
0.073
0.000
***
anxiety
time
0.035
0.042
0.405
anxiety
group_2
0.190
0.102
0.064
anxiety
time*group_2
-0.124
0.060
0.038
*
depression
Intercept
2.827
0.077
0.000
***
depression
time
0.022
0.043
0.612
depression
group_2
0.349
0.108
0.001
**
depression
time*group_2
-0.237
0.062
0.000
***
volatility
Intercept
2.857
0.077
0.000
***
volatility
time
-0.016
0.046
0.735
volatility
group_2
0.155
0.109
0.157
volatility
time*group_2
-0.110
0.066
0.097
curiosity
Intercept
4.006
0.055
0.000
***
curiosity
time
-0.001
0.034
0.973
curiosity
group_2
-0.125
0.077
0.106
curiosity
time*group_2
0.075
0.048
0.120
aesthetic
Intercept
3.722
0.065
0.000
***
aesthetic
time
-0.010
0.038
0.782
aesthetic
group_2
-0.122
0.091
0.179
aesthetic
time*group_2
0.035
0.054
0.520
imagination
Intercept
3.774
0.063
0.000
***
imagination
time
-0.008
0.043
0.860
imagination
group_2
-0.141
0.089
0.112
imagination
time*group_2
0.076
0.061
0.216
One significant group_2 effect: higher depression trait level in Group 2 at baseline compared to Group 3. Significant differences in the changes over time in current personality trait levels (timeXgroup) for extraversion, neuroticism, and depression (at p < .01). Significant changes over time in current personality trait levels (main effects of time) for productiveness (independent of group membership).
Plot of main effects: productiveness
Show the code
ggeffects::ggpredict(df_manip_check_curr_23$productiveness, terms =c("time_d[0,1]", "group_2[0,1]")) |>plot() +aes(linetype=group, color=group, shape=group) +geom_point() +theme_light() +scale_x_continuous(breaks =c(0,1), labels =c("T1", "T2")) +theme(panel.grid.minor.x =element_blank()) +labs(title ="Productiveness", x ="Time", y ="Predicted values of\nproductiveness",linetype="Group\n(0 = Group 3,\n1 = Group 2)", color="Group\n(0 = Group 3,\n1 = Group 2)", shape="Group\n(0 = Group 3,\n1 = Group 2)")
Group interaction effects: extraversion, neuroticism, and depression
Show the code
ggeffects::ggpredict(df_manip_check_curr_23$extraversion, terms =c("time_d[0,1]", "group_2[0,1]")) |>plot() +aes(linetype=group, color=group, shape=group) +geom_point() +theme_light() +scale_x_continuous(breaks =c(0,1), labels =c("T1", "T2")) +theme(panel.grid.minor.x =element_blank()) +labs(title ="Extraversion", x ="Time", y ="Predicted values of\nextraversion",linetype="Group\n(0 = Group 3,\n1 = Group 2)", color="Group\n(0 = Group 3,\n1 = Group 2)", shape="Group\n(0 = Group 3,\n1 = Group 2)")
Show the code
ggeffects::ggpredict(df_manip_check_curr_23$neuroticism, terms =c("time_d[0,1]", "group_2[0,1]")) |>plot() +aes(linetype=group, color=group, shape=group) +geom_point() +theme_light() +scale_x_continuous(breaks =c(0,1), labels =c("T1", "T2")) +theme(panel.grid.minor.x =element_blank()) +labs(title ="Neuroticism", x ="Time", y ="Predicted values of\nneuroticism",linetype="Group\n(0 = Group 3,\n1 = Group 2)", color="Group\n(0 = Group 3,\n1 = Group 2)", shape="Group\n(0 = Group 3,\n1 = Group 2)")
Show the code
ggeffects::ggpredict(df_manip_check_curr_23$depression, terms =c("time_d[0,1]", "group_2[0,1]")) |>plot() +aes(linetype=group, color=group, shape=group) +geom_point() +theme_light() +scale_x_continuous(breaks =c(0,1), labels =c("T1", "T2")) +theme(panel.grid.minor.x =element_blank()) +labs(title ="Depression", x ="Time", y ="Predicted values of\ndepression",linetype="Group\n(0 = Group 3,\n1 = Group 2)", color="Group\n(0 = Group 3,\n1 = Group 2)", shape="Group\n(0 = Group 3,\n1 = Group 2)")
Descriptive statistics by group
group: 0
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 176 3.07 0.76 3.08 3.05 0.8 1 5 4 0.15 -0.46 0.06
------------------------------------------------------------
group: 1
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 353 2.88 0.75 2.83 2.86 0.74 1 5 4 0.18 -0.26 0.04
Welch Two Sample t-test
data: extra_comb_curr by interv
t = 2.7368, df = 347.5, p-value = 0.006522
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
99 percent confidence interval:
0.01026637 0.37255887
sample estimates:
mean in group 0 mean in group 1
3.068655 2.877243
cohen.d(extra_comb_curr ~ interv, data = df_sbsa3 %>%filter(time==1), alpha=.01)
Call: cohen.d(x = extra_comb_curr ~ interv, alpha = 0.01, data = df_sbsa3 %>%
filter(time == 1))
Cohen d statistic of difference between two means
lower effect upper
extra_comb_curr -0.49 -0.25 -0.01
Multivariate (Mahalanobis) distance between groups
[1] 0.25
r equivalent of difference between two means
extra_comb_curr
-0.12
# agreepsych::describeBy(df_sbsa3 %>%filter(time==1) %>%pull(agree_comb_curr), group = df_sbsa3 %>%filter(time==1) %>%pull(interv))
Descriptive statistics by group
group: 0
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 176 3.69 0.62 3.71 3.72 0.56 1.75 5 3.25 -0.35 0.06 0.05
------------------------------------------------------------
group: 1
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 353 3.65 0.57 3.67 3.67 0.62 1.75 4.92 3.17 -0.39 0.06 0.03
Welch Two Sample t-test
data: agree_comb_curr by interv
t = 0.64373, df = 326.78, p-value = 0.5202
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
99 percent confidence interval:
-0.1087340 0.1806259
sample estimates:
mean in group 0 mean in group 1
3.688920 3.652975
cohen.d(agree_comb_curr ~ interv, data = df_sbsa3 %>%filter(time==1), alpha=.01)
Call: cohen.d(x = agree_comb_curr ~ interv, alpha = 0.01, data = df_sbsa3 %>%
filter(time == 1))
Cohen d statistic of difference between two means
lower effect upper
agree_comb_curr -0.3 -0.06 0.18
Multivariate (Mahalanobis) distance between groups
[1] 0.061
r equivalent of difference between two means
agree_comb_curr
-0.03
# conscpsych::describeBy(df_sbsa3 %>%filter(time==1) %>%pull(consc_comb_curr), group = df_sbsa3 %>%filter(time==1) %>%pull(interv))
Descriptive statistics by group
group: 0
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 176 3.54 0.77 3.58 3.58 0.74 1.75 5 3.25 -0.41 -0.45 0.06
------------------------------------------------------------
group: 1
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 353 3.35 0.74 3.42 3.37 0.74 1.17 5 3.83 -0.26 -0.2 0.04
Welch Two Sample t-test
data: consc_comb_curr by interv
t = 2.7852, df = 338.3, p-value = 0.005651
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
99 percent confidence interval:
0.0136436 0.3765884
sample estimates:
mean in group 0 mean in group 1
3.542614 3.347498
cohen.d(consc_comb_curr ~ interv, data = df_sbsa3 %>%filter(time==1), alpha=.01)
Call: cohen.d(x = consc_comb_curr ~ interv, alpha = 0.01, data = df_sbsa3 %>%
filter(time == 1))
Cohen d statistic of difference between two means
lower effect upper
consc_comb_curr -0.5 -0.26 -0.02
Multivariate (Mahalanobis) distance between groups
[1] 0.26
r equivalent of difference between two means
consc_comb_curr
-0.12
# neuropsych::describeBy(df_sbsa3 %>%filter(time==1) %>%pull(neuro_comb_curr), group = df_sbsa3 %>%filter(time==1) %>%pull(interv))
Descriptive statistics by group
group: 0
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 176 3.03 0.94 3 3.04 1.11 1.08 4.92 3.83 -0.03 -0.89 0.07
------------------------------------------------------------
group: 1
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 353 3.23 0.86 3.25 3.25 0.86 1.25 5 3.75 -0.23 -0.59 0.05
Welch Two Sample t-test
data: neuro_comb_curr by interv
t = -2.3139, df = 322.55, p-value = 0.0213
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
99 percent confidence interval:
-0.41266814 0.02332946
sample estimates:
mean in group 0 mean in group 1
3.031723 3.226393
cohen.d(neuro_comb_curr ~ interv, data = df_sbsa3 %>%filter(time==1), alpha=.01)
Call: cohen.d(x = neuro_comb_curr ~ interv, alpha = 0.01, data = df_sbsa3 %>%
filter(time == 1))
Cohen d statistic of difference between two means
lower effect upper
neuro_comb_curr -0.02 0.22 0.46
Multivariate (Mahalanobis) distance between groups
[1] 0.22
r equivalent of difference between two means
neuro_comb_curr
0.1
# opennpsych::describeBy(df_sbsa3 %>%filter(time==1) %>%pull(openn_comb_curr), group = df_sbsa3 %>%filter(time==1) %>%pull(interv))
Descriptive statistics by group
group: 0
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 176 3.83 0.64 3.83 3.85 0.62 2.08 5 2.92 -0.23 -0.56 0.05
------------------------------------------------------------
group: 1
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 353 3.72 0.64 3.67 3.74 0.62 1.75 5 3.25 -0.33 -0.06 0.03
Welch Two Sample t-test
data: openn_comb_curr by interv
t = 1.9307, df = 350.41, p-value = 0.05433
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
99 percent confidence interval:
-0.03895913 0.26713590
sample estimates:
mean in group 0 mean in group 1
3.833807 3.719718
cohen.d(openn_comb_curr ~ interv, data = df_sbsa3 %>%filter(time==1), alpha=.01)
Call: cohen.d(x = openn_comb_curr ~ interv, alpha = 0.01, data = df_sbsa3 %>%
filter(time == 1))
Cohen d statistic of difference between two means
lower effect upper
openn_comb_curr -0.42 -0.18 0.06
Multivariate (Mahalanobis) distance between groups
[1] 0.18
r equivalent of difference between two means
openn_comb_curr
-0.08
8.3.2 Well-being
# swlspsych::describeBy(df_sbsa3 %>%filter(time==1) %>%pull(swls), group = df_sbsa3 %>%filter(time==1) %>%pull(interv))
Descriptive statistics by group
group: 0
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 176 2.94 1 3 2.94 1.19 1 5 4 -0.06 -0.8 0.08
------------------------------------------------------------
group: 1
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 353 2.69 1 2.6 2.66 1.19 1 5 4 0.18 -0.83 0.05
Welch Two Sample t-test
data: swls by interv
t = 2.7266, df = 349.3, p-value = 0.006721
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
99 percent confidence interval:
0.01260011 0.49016193
sample estimates:
mean in group 0 mean in group 1
2.937500 2.686119
cohen.d(swls ~ interv, data = df_sbsa3 %>%filter(time==1), alpha=.01)
Call: cohen.d(x = swls ~ interv, alpha = 0.01, data = df_sbsa3 %>%
filter(time == 1))
Cohen d statistic of difference between two means
lower effect upper
swls -0.49 -0.25 -0.01
Multivariate (Mahalanobis) distance between groups
[1] 0.25
r equivalent of difference between two means
swls
-0.12
# meaningpsych::describeBy(df_sbsa3 %>%filter(time==1) %>%pull(meaning), group = df_sbsa3 %>%filter(time==1) %>%pull(interv))
Descriptive statistics by group
group: 0
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 176 3.77 1.17 3.8 3.77 1.04 1 7 6 -0.05 -0.01 0.09
------------------------------------------------------------
group: 1
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 353 3.67 1.12 3.6 3.61 1.04 1 7 6 0.52 0.24 0.06
Welch Two Sample t-test
data: meaning by interv
t = 0.87265, df = 336.74, p-value = 0.3835
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
99 percent confidence interval:
-0.1832919 0.3695107
sample estimates:
mean in group 0 mean in group 1
3.767614 3.674504
cohen.d(meaning ~ interv, data = df_sbsa3 %>%filter(time==1), alpha=.01)
Call: cohen.d(x = meaning ~ interv, alpha = 0.01, data = df_sbsa3 %>%
filter(time == 1))
Cohen d statistic of difference between two means
lower effect upper
meaning -0.32 -0.08 0.16
Multivariate (Mahalanobis) distance between groups
[1] 0.082
r equivalent of difference between two means
meaning
-0.04
# selfespsych::describeBy(df_sbsa3 %>%filter(time==1) %>%pull(selfes), group = df_sbsa3 %>%filter(time==1) %>%pull(interv))
Descriptive statistics by group
group: 0
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 176 3.44 0.93 3.5 3.46 1.04 1.2 5 3.8 -0.17 -0.95 0.07
------------------------------------------------------------
group: 1
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 353 3.23 0.86 3.1 3.23 0.89 1.1 5 3.9 0.07 -0.67 0.05
Welch Two Sample t-test
data: selfes by interv
t = 2.5001, df = 323.94, p-value = 0.01291
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
99 percent confidence interval:
-0.007620598 0.426558919
sample estimates:
mean in group 0 mean in group 1
3.442614 3.233144
cohen.d(selfes ~ interv, data = df_sbsa3 %>%filter(time==1), alpha=.01)
Call: cohen.d(x = selfes ~ interv, alpha = 0.01, data = df_sbsa3 %>%
filter(time == 1))
Cohen d statistic of difference between two means
lower effect upper
selfes -0.48 -0.24 0
Multivariate (Mahalanobis) distance between groups
[1] 0.24
r equivalent of difference between two means
selfes
-0.11
# conceptpsych::describeBy(df_sbsa3 %>%filter(time==1) %>%pull(concept), group = df_sbsa3 %>%filter(time==1) %>%pull(interv))
Descriptive statistics by group
group: 0
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 176 3.16 0.91 3.17 3.16 1.05 1.25 5 3.75 0.05 -0.91 0.07
------------------------------------------------------------
group: 1
vars n mean sd median trimmed mad min max range skew kurtosis se
X1 1 353 3.06 0.85 3 3.03 0.86 1.33 5 3.67 0.32 -0.73 0.05
Welch Two Sample t-test
data: concept by interv
t = 1.1862, df = 328.92, p-value = 0.2364
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
99 percent confidence interval:
-0.1159972 0.3119046
sample estimates:
mean in group 0 mean in group 1
3.160985 3.063031
cohen.d(concept ~ interv, data = df_sbsa3 %>%filter(time==1), alpha=.01)
Call: cohen.d(x = concept ~ interv, alpha = 0.01, data = df_sbsa3 %>%
filter(time == 1))
Cohen d statistic of difference between two means
lower effect upper
concept -0.35 -0.11 0.13
Multivariate (Mahalanobis) distance between groups
[1] 0.11
r equivalent of difference between two means
concept
-0.05